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

时间:2011-10-24 20:10:25

标签: c++ templates compiler-errors metaprogramming partial-specialization

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

#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.但是只要我向我的类添加模板参数,就像这样:

#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)抱怨这些错误:

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.

我看到这一点的方式,没有歧义,编译器应该能够解决所有问题并且就像一个参数案例一样工作。

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

2 个答案:

答案 0 :(得分:6)

你不能部分专门化函数 - 这包括成员函数。你只能部分专门化整个类

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

(我在这里定义了内联函数;当然没有必要。)

答案 1 :(得分:6)


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

Philippe,今天早上回复你的评论,根据标准,你不能部分专门化一个类模板的成员,你只能完全专门化它们(无论是类模板,函数,函数模板等) ...)。在第一个示例中,您完全专注于成员函数foo。在你的第二个例子中,你是部分专业化的,为什么它不会编译。你可以通过这种方式完全专注:

template< >
inline int Test< int, 2 >::foo()
{...}

虽然Konrad的代码snipet完全合法,但我不确定为什么Philippe的代码无法编译的原因是正确的。 (尽管如Konrad所提到的,你不能部分专门化一个功能模板。)

Philippe的代码中的问题在于我们正在声明一个类模板,而不是一个函数模板。因此,部分特殊化定义需要部分类模板特化声明才能合法。

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