Как мне сделать эту явную специализацию?
-
28-09-2019 - |
Вопрос
Возможен следующий дизайн?
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 - это, без проблем с компиляцией при специализации с помощью встроенных определений, но для специализаций с ненутренными определениями после того, как есть более чем одна версия, которую она не успешно скомпилирована.