I have a struct that works as a wrapper for other types as follows:
template<typename T>
struct A {
  A& operator=(const T& value){
    m_value = value;
    return *this;
  }
  operator T() const {
    return m_value;
  }
private:
  T m_value;
};
I use it like this:
int main() {
  A<int> a;
  a = 5;                  // Copy assignment constructor
  std::cout << a << "\n"; // Implicit conversion to int
}
which works as expected. My problem occurs when using non-fundamental types as the following example shows:
int main() {
  A<std::complex<int>> c;
  c = std::complex<int>(2, 2);  
  std::cout << c << "\n";
}
The snippet above raises an invalid operands to binary expression error.
Why does this error occur? Why isn't the overloaded operator << of std::complex<int> used with the implicitly converted A<std::complex<int>>?
The stream operators for std::complex are template functions.  They will not be invoked unless you actual have a std::complex as no conversions happens in template argument deduction.  This means the compiler will not find a suitable overload to print a A<std::complex<int>>
You're first case for works because std::basic_ostream::operator << is overloaded to take an int and you are allowed one user defined conversion is overload resolution.
As a work arround you can define your own operator << that takes your wrapper and forward to the underlying types' operator <<.  That would look like
template<typename T>
std::ostream& operator <<(std::ostream& os, const A<T>& a)
{
    return os << static_cast<T>(a);
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With