Вопрос

Возможен следующий дизайн?

template <typename T>
class Test{
 public:
  template <typename Z>
  void doSomething();
  //rest of things
 private:
  T obj;
  //some things
};

Теперь, если это было возможно, я бы проделал несколько явных специализаций для дошуточного то, что в конце у меня будут некоторые версии, как приведенные ниже:

void doSomething<int>(){
 //do something
}
void doSomething<double>(){
 //do something
}
...etc

Что кажется невозможным, я не могу найти какой-либо синтаксис, чтобы сделать работу, то я подумал, возможно, дизайн должен быть, как следует так, чтобы все шаблонные аргументы должны быть переданы на сам классный класс:

template <typename T,typename Z>
class Test{
 public:
  void doSomething();
  //rest of things
 private:
  T obj;
  //some things
};

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

template <typename T>
void Test<T,int>::doSomething(){
 //do something
}
template <typename T>
void Test<T,double>::doSomething(){
 //do something
}
...etc

Я получил следующие ошибки для явной специализации:
Ошибка № 1: Список аргументов шаблона Следующий именем шаблона класса должен перечислить параметры в порядке, используемом в списке параметров шаблона.
Ошибка № 2: «Container1»: слишком мало шаблонов аргументов.

Это было полезно?

Решение

Для явного специализации doSomething Вы должны также явно специализироваться Test.

От 14.7.3 / 18:

В явной декларации специализации для члена шаблона класса или шаблона члена, который появляется в области пространства имен, шаблон участника и некоторые из шаблонов его ограждения могут оставаться неспециализированными, За исключением того, что Декларация не должна четко специализироваться на шаблон класса члена, если его шаблоны включения класса не являются явными специализированными, а также.

Другие советы

Вы не можете явно специализируетесь на шаблон участника, если его шаблоны с приложными классами также не являются явными специализированными.

Так только что-то вроде это будет работать:

template<> template<>
void Test<int>::doSomething<int>()
{
}

Вы всегда можете сделать функцию встроенным

template <class T>
class Test
{
public:
 template <class Z>
 void doSomething() { cout << "default" << endl; }

 template<>
 void doSomething<int>() { cout << "int" << endl;}
 template<>
 void doSomething<double>() { cout << "double" << endl; }
private:
 T obj;
};

Я думаю, что это придирчиво. Я полагаю, вы не можете это сделать, читать это.

Не уверен, что это ошибка в G ++, но это компилирует и производит то, что я ожидаю.

#include<typeinfo>
#include<iostream>

template<typename T>
class Test
{
public:
    template<typename Z>
    void doSomething();

private:
    T obj;
};

template<typename T>
template<typename Z>
void Test<T>::doSomething()
{
    Z val;
    std::cout << __func__ << ": type " << typeid(val).name() << std::endl;
}

int main(int argc, char *argv[])
{
    Test<double> a;
    a.doSomething<int>();
    a.doSomething<double>();
}

ICECRime опубликовал временный ответ, и он составляется из-за некоторой ошибки, вероятно, Visual C ++ 2008:

template <typename T>
class Test{
 public:
  template <typename Z>
  void doSomething();
  //rest of things
 private:
  T obj;
  //some things
};
template <>
template <typename T>
void Test<T>::doSomething<int>(){
 //do something
}

Проверьте его текущий ответ. Смешная вещь, по крайней мере, с VC ++ 2008 - это, без проблем с компиляцией при специализации с помощью встроенных определений, но для специализаций с ненутренными определениями после того, как есть более чем одна версия, которую она не успешно скомпилирована.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top