Matt Phillips
Matt Phillips

Reputation: 9691

templated casting operator and partial specialization

I want to templatize the casting operator with a specialization for bool, but it's not working.

template<typename T> //Don't know if the fact that C is templated itself is relevant here
class C
{ 
...
        template<typename U> operator U() const { return another_namespace::MyCast<U>(*this); }
        template<> operator bool() const { return IsValid(); } 
};

This gives me (g++ 4.6)

explicit specialization in non-namespace scope ‘class C< T>’

Now just

operator bool() const { return IsValid(); }

by itself works, as does MyCast (it's a friend function declared in an external namespace). Is there any way I can get the intended behHoavior here?

Edit: I have subsequently found this, looks like the same basic question, however the answer (which gives a very complicated solution) looks designed specifically for strings. Also, the issue there turned out to be ambiguity, which I think is not the problem here--I get a very different compiler error message.

Upvotes: 0

Views: 921

Answers (2)

TrueY
TrueY

Reputation: 7610

I tried to specialize the type cast operator template and I had the same problem, when I defined the specialization inside the class definition. But when I moved outside, it worked like a charm!

Example definition:

struct A {
  int i;
  A(int v) : i(v) { 
    cout << __PRETTY_FUNCTION__ << endl; 
  }
  template <typename T>
  operator T() { 
    cout << __PRETTY_FUNCTION__ << " - NOT IMPLEMENTED" << endl; 
    throw; 
    return 0;
  }

  // Compilation error
  // error: explicit specialization in non-namespace scope ‘struct A’
  //template <>
  //operator double() { 
  //  cout << __PRETTY_FUNCTION__ << " - !!! IMPLEMENTED" << endl; 
  //  return (double)i; 
  //}
};
// But this works well!!
template <>
A::operator double() { 
  cout << __PRETTY_FUNCTION__ << " - !!! IMPLEMENTED" << endl; 
  return (double)i; 
}

Example main:

A a(5);
double d = a;
long l = a;

Output:

A::A(int)
A::operator T() [with T = double] - !!! IMPLEMENTED
A::operator T() [with T = long int] - NOT IMPLEMENTED
terminate called without an active exception

Tested: g++ (Debian 4.7.2-5) 4.7.2 without any extra args.

I will try under much older g++ as well...

Upvotes: 0

sth
sth

Reputation: 229603

You can overload conversion operators, so simply using a non-templated version of the operator bool() should work:

template<typename T>
class C
{ 
...
        template<typename U> operator U() const { ... }
        operator bool() const { ... } 
};

Upvotes: 3

Related Questions