具有多个模板参数错误的模板部分特化

当我在一个带有一个模板参数的类上使用模板部分特化时,我可以特化这样的方法:

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;
}

方法 foo 专门用于 Dim = 1.但是一旦我向我的类添加模板参数,就像这样:

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;
}

编译器(VS2010)抱怨这些错误:

The compiler (of VS2010) complains with these errors:

1>c:documents and settingscayouettemy documentscodelocal	esttemplatespecializationmain.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 settingscayouettemy documentscodelocal	esttemplatespecializationmain.cpp(20): error C2995: 'int Test<T,Dim>::foo(void)' : function template has already been defined
1>          c:documents and settingscayouettemy documentscodelocal	esttemplatespecializationmain.cpp(7) : see declaration of 'Test<T,Dim>::foo'
1>c:documents and settingscayouettemy documentscodelocal	esttemplatespecializationmain.cpp(20): error C2976: 'Test<T,Dim>' : too few template arguments
1>c:documents and settingscayouettemy documentscodelocal	esttemplatespecializationmain.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 settingscayouettemy documentscodelocal	esttemplatespecializationmain.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.

如果 C++ 不支持,请解释原因.

If this is not supported in C++, please explain why.

推荐答案


编辑,因为我还不能发表评论(50 代表呵呵)...


Editing since I cannot post comments yet (50 rep heh)...

Philippe,今天早上回复你的评论,按照标准你不能部分特化类模板的成员,你只能完全特化它们(无论是类模板、函数、函数模板等)……).在您的第一个示例中,您完全特化了成员函数 foo.在你的第二个例子中,你是部分专业的,这是它无法编译的原因.您可以通过这种方式完全专业化:

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()
{...}

<小时>

尽管 Konrad 的代码片段是完全合法的,但我不确定 Philippe 代码无法编译的原因是否正确.(虽然,正如 Konrad 提到的,你不能部分特化一个函数模板).


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

Philippe 代码中的问题是,我们声明的是类模板而不是函数模板.因此,为了使部分特化定义合法,需要一个部分类模板特化声明.

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;
}

相关文章