0

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.

Community
  • 1
  • 1
Matt Phillips
  • 9,465
  • 8
  • 44
  • 75
  • 1
    Doesn't it do what you want if you just use the non-templated `operator bool()`? – sth Dec 01 '11 at 19:53
  • @sth Ha! Looks like it. Turns out this is in a big program and I have a lot of other bugs I have to resolve to get it to compile, but the compiler made it past the file containing class C. Didn't realize non-specialization was an option. Put your response as an answer and you'll get the credit, so long as everything works out. – Matt Phillips Dec 01 '11 at 20:00
  • 1
    `namespace::MyCast(` I don't think that part is right. Is it? – Mooing Duck Dec 01 '11 at 20:08
  • @Mooing Duck No, that's fine. MyCast is declared/defined outside of C. But actually, since 'namespace' is a reserved word, you're correct that that is a potentially confusing syntax error. Edited accordingly. – Matt Phillips Dec 01 '11 at 20:11

2 Answers2

3

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 { ... } 
};
sth
  • 222,467
  • 53
  • 283
  • 367
0

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

TrueY
  • 7,360
  • 1
  • 41
  • 46