0

Why does the following code fail to compile?

template <typename T>
struct X
{
 template <typename R>
 R default_value();
};
template <typename T>
int X<T>::default_value<int>()
{
 return -1;
}

it says

x.cpp:17:30: error: template-id ‘default_value<int>’ in declaration of primary template
x.cpp:17:5: error: prototype for ‘int X<T>::default_value()’ does not match any in class ‘X<T>’
x.cpp:13:7: error: candidate is: template<class T> template<class R> R X::default_value()

I also tried to do

template <typename T>
template <>
int X<T>::default_value<int>()
{
 return -1;
}

but this gives me another compilation error

prog.cpp:11: error: invalid explicit specialization before '>' token
prog.cpp:11: error: enclosing class templates are not explicitly specialized
prog.cpp:12: error: template-id 'default_value<int>' for 'int X<T>::default_value()' does not match any template declaration

I also tried doing the same for structures

template <typename T>
struct X
{
 template <typename R> struct default_value;
};
template <typename T>
template <>
struct X<T>::default_value<int>
{
 static int get() { return -1; }
};

same issue.

How to solve that?

asked Nov 19, 2013 at 16:00
3
  • why template on the return type, function cannot be overloaded based on return type. Commented Nov 19, 2013 at 16:08
  • I'm not overloading it, I'm doing specialization. Well, but basically I started from structure specialization and encountered the same error. Commented Nov 19, 2013 at 16:11
  • The same for non-method function works fine. ideone.com/C1YTBa Commented Nov 19, 2013 at 16:15

2 Answers 2

2

One cannot explicitly specialize member templates. Consider:

template <class T>
struct X
{
 template <class U> struct Y;
};

...Now (imagine we could do this):

template <class T>
 template <>
 struct X<T>::Y<int>
{};

...For X of which T are we explicitly specializing?

What if, after the point of definition of our explicit specialization, someone does this in one compilation unit...

void foo()
{
 X<int>::Y<int> xy;
}

... and then this in another...(valid code, btw).

template <>
 template<>
 struct X<int>::Y<int>
{};
void foo()
{
 X<int>::Y<int> xy;
}

... which would imply multiple definitions of the same class???

As mentioned previously, this is treated well here

Now, considering that the default value actually depends on the type T, perhaps one can get it from the type T.

template <class T>
struct X
{
 static T defaultValue(){ return T::defaultValue(); }
};

or better yet, one could change the behavior of defaultValue based on whether T has the member defaultValue.

answered Nov 19, 2013 at 16:43
Sign up to request clarification or add additional context in comments.

Comments

0
template <typename T>
template <>
int X<T>::default_value<int>()
{
 return -1;
}

should be fine. Similar topic...

answered Nov 19, 2013 at 16:01

3 Comments

I tried that already, it says x.cpp:17:11: error: invalid explicit specialization before ‘>’ token x.cpp:17:11: error: enclosing class templates are not explicitly specialized x.cpp:18:5: error: template-id ‘default_value<int>’ for ‘int X<T>::default_value()’ does not match any template declaration
@axe: What kind of compiler are you using?
Locally gcc 4.6.3, The same issue reproduces on ideone.com with gcc 4.8.1

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.