5

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

#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++ 不支持,请解释原因。

4

2 回答 2

6

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

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

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

尽管 Konrad 的代码片段是完全合法的,但我不确定 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;
}
于 2011-10-24T21:16:40.200 回答
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;
  }
};

(我在这里定义了内联函数;这当然不是必需的。)

于 2011-10-24T20:23:17.573 回答