Reputation: 752
If I remove the template specialization part (the one that tries to print "Test 2"), the code compiles fine, but I'd like to be able to have a special case that runs a different code path that looks clean to outside users.
#include <iostream>
using namespace std;
struct SpecialType {};
template<typename A , typename B = SpecialType>
class Test
{
public:
class TestInner
{
public:
TestInner& operator* ();
};
};
template<typename A , typename B>
typename Test<A , B>::TestInner& Test<A , B>::TestInner::operator* ()
{
cout << "Test 1" << endl;
return *this;
}
// If the following is removed, everything compiles/works, but I want this alternate code path:
template<typename A>
typename Test<A , SpecialType>::TestInner& Test<A , SpecialType>::TestInner::operator* ()
{
cout << "Test 2" << endl;
return *this;
}
int main()
{
Test<int , SpecialType>::TestInner test;
*test;
return 0;
}
What am I doing wrong?
Edit: By the way, the compiler error reads:
main.cpp:26:44: error: 'Test<A, SpecialType>::TestInner' is not a type
typename Test<A , SpecialType>::TestInner& Test<A , SpecialType>::TestInner::operator* ()
^
main.cpp:26:89: error: invalid use of dependent type 'typename Test<A, SpecialType>::TestInner'
typename Test<A , SpecialType>::TestInner& Test<A , SpecialType>::TestInner::operator* ()
^
Upvotes: 1
Views: 3447
Reputation: 75697
Add a declaration for the specialised class:
template<typename A>
class Test<A, SpecialType>
{
public:
class TestInner
{
public:
TestInner& operator* ();
};
};
The problem is that you define an member for a specialization that is not declared. A specialization of a templated class does not share any members or methods with the generalised template, so the declaration of the generalised template doesn't serve as a declaration of any specialisations of that template class.
Consider this:
template <class T>
class Foo {
void GeneralFunction(T x);
}
and a specialization:
template <>
class Foo<int> {
void SpecialisedFunction(int x);
}
Here, Foo</*anything except int*/>
has only the method GeneralFunction
whereas Foo<int>
has only the method SpecialisedFunction
.
By the same logic, this is allowed also:
template<>
class Foo<float> {
float GeneralFunction; //here GeneralFunction is a data member, not a method.
}
Long story short you need to declare you specialisation.
Upvotes: 7