5

テンプレート引数が 1 つのクラスでテンプレートの部分特殊化を使用すると、次のようにメソッドを特殊化できます。

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

私の見方では、あいまいさはなく、コンパイラはすべてを解決して、引数が 1 つの場合と同じように機能するはずです。

これが C++ でサポートされていない場合は、その理由を説明してください。

4

2 に答える 2

6

コメントをまだ投稿できないので編集中(50 rep heh)...

フィリップ、今朝のコメントに応えて、標準によれば、クラステンプレートのメンバーを部分的に特殊化することはできず、完全に特殊化することしかできません(クラステンプレート、関数、関数テンプレートなど)。 )。最初の例では、メンバー関数fooを完全に特殊化しています。2番目の例では、部分的に専門化しているため、コンパイルされません。あなたはそれをこのように完全に専門化することができます:

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

Konradのコードスニペットは完全に合法ですが、Philippeのコードがコンパイルされない理由が正しいかどうかはわかりません。(ただし、Konradが述べたように、関数テンプレートを部分的に特殊化することはできません)。

フィリップのコードで目前にある問題は、関数テンプレートではなくクラステンプレートを宣言していることです。したがって、部分的な特殊化の定義が有効であるためには、部分的なクラステンプレートの特殊化宣言が必要です。

#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 に答える