This code compiles in CodeGear 2009 and Visual Studio 2010 but not gcc. Why?
class Foo
{
public:
operator int() const;
template <typename T> T get() const { return this->operator T(); }
};
Foo::operator int() const
{
return 5;
}
The error message is:
test.cpp: In member function `T Foo::get() const':
test.cpp:6: error: 'const class Foo' has no member named 'operator T'
It's a bug in G++. operator T
is an unqualified dependent name (because it has T
in it and lookup will thus be different depending on its type). As such it has to be looked up when instantiating. The Standard rules
Two names are the same if
- ...
- they are the names of user-defined conversion functions formed with the same type.
Thus the type name specified after the operator keyword doesn't have to match lexically in any way. You can apply the following work-around to force GCC treating it as a dependent name
template<typename T, typename>
struct identity { typedef T type; };
class Foo
{
public:
operator int() const;
template <typename T> T get() const {
return this->identity<Foo, T>::type::operator T();
}
};
I'm not sure what the exact rules for the names of C++ operators are, but I believe it's trying to call operator T()
instead of operator int()
. Why not just use a cast:
template <typename T> T get() const { return static_cast<T>(*this); }
I haven't tested this but I believe this will accomplish more or less the same thing. If not, there should be a way to accomplish this without having to call operator T()
directly. That's what overloaded operators are for, after all.
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