问题
When I use template partial specialization on a class with one template argument, I can specialize a method like this:
#include <cstdlib>
template< std::size_t Dim >
class Test
{
public:
int foo();
};
template< std::size_t Dim >
inline int Test< Dim >::foo()
{
return 0;
}
template<>
inline int Test< 1 >::foo()
{
return 1;
}
int main()
{
Test< 2 > wTest2;
Test< 1 > wTest1;
wTest2.foo();
wTest1.foo();
return 0;
}
The method foo is specialized for Dim = 1. But as soon as I add a template argument to my class, like this:
#include <cstdlib>
template< typename T, std::size_t Dim >
class Test
{
public:
int foo();
};
template< typename T, std::size_t Dim >
inline int Test< T, Dim >::foo()
{
return 0;
}
template< typename T >
inline int Test< T, 1 >::foo()
{
return 1;
}
int main()
{
Test< double, 2 > wTest2;
Test< double, 1 > wTest1;
wTest2.foo();
wTest1.foo();
return 0;
}
The compiler (of VS2010) complains with these errors:
1>c:\documents and settings\cayouette\my documents\codelocal\testtemplatespecialization\main.cpp(20): error C3860: template argument list following class template name must list parameters in the order used in template parameter list
1>c:\documents and settings\cayouette\my documents\codelocal\testtemplatespecialization\main.cpp(20): error C2995: 'int Test<T,Dim>::foo(void)' : function template has already been defined
1> c:\documents and settings\cayouette\my documents\codelocal\testtemplatespecialization\main.cpp(7) : see declaration of 'Test<T,Dim>::foo'
1>c:\documents and settings\cayouette\my documents\codelocal\testtemplatespecialization\main.cpp(20): error C2976: 'Test<T,Dim>' : too few template arguments
1>c:\documents and settings\cayouette\my documents\codelocal\testtemplatespecialization\main.cpp(26): error C2264: 'Test<T,Dim>::foo' : error in function definition or declaration; function not called
1> with
1> [
1> T=double,
1> Dim=2
1> ]
1>c:\documents and settings\cayouette\my documents\codelocal\testtemplatespecialization\main.cpp(27): error C2264: 'Test<T,Dim>::foo' : error in function definition or declaration; function not called
1> with
1> [
1> T=double,
1> Dim=1
1> ]
1>
1>Build FAILED.
The way I see this, there is no ambiguity and the compiler should be able to resolve everything and work just like the one argument case.
If this is not supported in C++, please explain why.
回答1:
You cannot partially specialise functions – this includes member functions. You can only partially specialise the whole class:
template< typename T, std::size_t Dim >
class Test
{
public:
int foo()
{
return 0;
}
};
template< typename T >
class test< T, 1 >
{
public:
int foo()
{
return 1;
}
};
(I’ve defined the functions inline here; that of course isn’t necessary.)
回答2:
Editing since I cannot post comments yet (50 rep heh)...
Philippe, in response to your comment this morning, according to the standard you cannot partially specialize a member of a class template, you can only fully specialize them (whether it be a class template, a function, a function template, etc...). In your first example, you are fully specializing the member function foo. In your second example, you are partially specializing, reason why it will not compile. You can fully specialize it this way:
template< >
inline int Test< int, 2 >::foo()
{...}
Although Konrad's code snipet is perfectly legal, I'm not sure the reason provided as to why Philippe's code doesn't compile is correct. (Although, as Konrad mentionned, you cannot partially specialize a function template).
The issue at hand, in Philippe's code, is that we are declaring a class template and not a function template. Hence, a partial class template specialization declaration is needed for the partial specialization definition to be legal.
#include <cstdlib>
template< typename T, std::size_t Dim >
class Test
{
public:
int foo();
};
template < typename T >
class Test < T, 1 >
{
public:
int foo();
};
template< typename T, std::size_t Dim >
inline int Test< T, Dim >::foo()
{
return 0;
}
template< typename T >
inline int Test< T, 1 >::foo()
{
return 1;
}
int main()
{
Test< double, 2 > wTest2;
Test< int, 1 > wTest1;
wTest2.foo();
wTest1.foo();
return 0;
}
来源:https://stackoverflow.com/questions/7881362/template-partial-specialization-with-multiple-template-argument-error