Very strange bug when implementing a custom power operator

114 Views Asked by At

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?

0

There are 0 best solutions below