Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error when using operator << with implicitly converted non-fundamental data types [duplicate]

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>>?

like image 699
Orzowei Avatar asked Jun 14 '18 17:06

Orzowei


1 Answers

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);
}
like image 57
NathanOliver Avatar answered Sep 21 '22 02:09

NathanOliver