0

For an exercice, I writed a little class in C++ that cannot be casted to other types than the generic parameter T:

template <class T>
class pure
{
public:

pure(T const& attr)
{
    this->attr = attr;
}

~pure()
{
}

T& operator=(T const& attr)
{
    return attr;
}

operator T()
{
    return attr;
}

template<typename U>
operator U() = delete;

private:
T attr;
};

And here is the main :

int main() 
{
pure<int> i = 15;

    //This won't compile, like I wanted
    //All the casts to other types than int won't compile
cout << (short)i;

    //BUT when I'm using mye pure object without a cast, I get a lot of   ambiguities errors
    cout << i;

system("PAUSE");
return 0; 
}

So, why the second cout doesn't work ? This should be work because I deleted all other possible casts than int. Thanks for help. Refrring to this may help to understand: Prevent an object to be casted to any but one type C++

Community
  • 1
  • 1
  • 1
    [Deleted functions participate in overload resolution](http://stackoverflow.com/questions/14085620/why-do-c11-deleted-functions-participate-in-overload-resolution). – chris Apr 04 '15 at 19:28

2 Answers2

3

Your code works fine if you overload the << operator for pure<T>.

#include <iostream>

template <class T>
class pure {
    T attr;

public:
    pure(T const& attr) {
        this->attr = attr;
    }

    T& operator=(T const& attr) {
        return attr;
    }

    operator T() {
        return attr;
    }

    template<typename U>
    operator U() = delete;
};

template<typename T>
std::ostream& operator<<(std::ostream& os, pure<T> p) {
    os << static_cast<T>(p);
    return os;
}

int main()
{
    using namespace std;
    pure<int> i = 15;

    //This won't compile, like I wanted
    //All the casts to other types than int won't compile
    cout << static_cast<short>(i);

    //Now works fine
    cout << i;

    return 0;
}
  • Pretty good answer, but I don't want to have to write tons of operators for resolve ambiguity on all operators ! Is there a way much easier ? Is exists a "wildcard" operator wich do an a static cast for each operator ? – Marc-Antoine Jacob Apr 04 '15 at 19:39
  • Unforunately no, there is no wildcard operator. You might be able to make due with macros to implement the operators you're interested in. – Mathias Vorreiter Pedersen Apr 04 '15 at 19:50
2

See Why do C++11-deleted functions participate in overload resolution? to understand why

 cout << i << endl;

doesn't work.

Workarounds:

  1. Provide an appropriate operator<<() overload.

  2. Remove the explicitly deleted cast operators.

The following code works:

#include <iostream>

template <typename T>
class pure
{
   public:
      operator T()
      {
         return 0;
      }

};

int main()
{
   pure<int> p;
   std::cout << p << std::endl;
}
Community
  • 1
  • 1
R Sahu
  • 204,454
  • 14
  • 159
  • 270