I've looked at this answer Can you make custom operators in C++? and tried to implement a custom power operator denoted by <power>, using some proxy objects. However, I have a very strange bug which makes my program only work when I print out a variable (The variable x in the definition of the class PowerExpression
).
Here's my code:
//
// Power.hpp
// Draft1.0
//
// Created by CYRUS LINDEN on 1/1/21.
// Copyright © 2021 CYRUS LINDEN. All rights reserved.
//
#ifndef Power_hpp
#define Power_hpp
#include <stdio.h>
//
// Power.hpp
// Experiments
//
// Created by CYRUS LINDEN on 1/1/21.
// Copyright © 2021 CYRUS LINDEN. All rights reserved.
//
#include <cmath>
#include <iostream>
const struct power_ {} power;
template <typename T>
struct PowerProxy
{
PowerProxy(const T& t): t_(t) {}
const T& t_;
inline operator T() const {
return t_;
}
};
template <typename T>
class BasePowerExpression;
template <typename T, typename U>
class PowerExpression {
public:
PowerExpression(const T& lhs, const U& rhs) : lhs_(lhs) , rhs_(rhs) {}
public:
const T& lhs_;
const U& rhs_;
inline operator T() const {
//std::cout << typeid(rhs_).name();
const T& x = static_cast<T>(rhs_);
// THIS IS THE LINE THAT CAUSES THE BUG. IF IT IS REMOVED, THE ANSWER IS 0.
std::cout << x << '\n';
return std::pow(lhs_, x);
}
};
template <typename T>
class BasePowerExpression{
public:
const T& lhs_;
const T& rhs_;
BasePowerExpression(const T& lhs, const T& rhs) : lhs_(lhs) , rhs_(rhs) {}
inline operator T() const {
return std::pow(lhs_, rhs_);
}
};
template <typename T>
inline auto operator<(const T& lhs, const power_& rhs)
{
return PowerProxy<T>(lhs);
}
template <typename T>
inline auto operator<(const BasePowerExpression<T>& lhs, const power_& rhs)
{
return lhs;
}
template <typename T, typename U>
inline auto operator<(const PowerExpression<T , U>& lhs, const power_& rhs)
{
return lhs;
}
template <typename T>
inline auto operator>(const PowerProxy<T>& lhs, const T& rhs)
{
return BasePowerExpression(lhs.t_, rhs);
}
template <typename T>
inline auto operator>(const BasePowerExpression<T>& lhs, const T& rhs)
{
return PowerExpression(lhs.lhs_, BasePowerExpression(lhs.rhs_, rhs));
;
}
template <typename T, typename U>
inline auto operator> (const PowerExpression<T , U>& lhs, const T& rhs) {
return PowerExpression(lhs.lhs_, PowerExpression(lhs.rhs_, rhs));
}
#endif /* Power_hpp */
and when trying to use it in main.cpp:
int main() {
std::cout << (2 <power> 2 <power> 3);
return 0;
}
This compiles fine and works fine and prints 256 . However, if I remove the line where I print x in the definition of class PowerExpression
, this just prints 0. This is very strange. I think my code must have some undefined behaviour in it, but I can't seem to find any. Can anyone help me out here?