Частичная специализация шаблона с ошибкой нескольких аргументов шаблона - PullRequest
5 голосов
/ 25 октября 2011

Когда я использую частичную специализацию шаблона в классе с одним аргументом шаблона, я могу специализировать метод следующим образом:

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

6 голосов
/ 25 октября 2011

Редактирование, так как я пока не могу оставлять комментарии (50 респ хех) ...

Филипп, отвечая на ваш комментарий сегодня утром, согласно стандарту, вы не можете частично специализировать члена классашаблон, вы можете только полностью специализировать их (будь то шаблон класса, функция, шаблон функции и т. д.).В первом примере вы полностью специализируете функцию-член foo.Во втором примере вы частично специализируете, причина, по которой он не будет компилироваться.Вы можете полностью специализировать его следующим образом:

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

Хотя фрагмент кода Конрада является совершенно законным, я не уверен, что причина того, почему код Филиппа не компилируется, верна.(Хотя, как упоминал Конрад, вы не можете частично специализировать шаблон функции).

Проблема в коде Филиппа заключается в том, что мы объявляем шаблон класса, а не шаблон функции.Следовательно, объявление специализации шаблона частичного класса необходимо для того, чтобы определение частичной специализации было допустимым.

#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;
}
6 голосов
/ 25 октября 2011

Вы не можете частично специализировать функции - сюда входят функции-члены. Вы можете только частично специализировать весь класс :

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

(здесь я определил встроенные функции; это, конечно, не нужно.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...