#c #templates #template-specialization
#c #шаблоны #шаблон-специализация
Вопрос:
Я видел много вопросов SO о специализации в контексте методов, но не функций, принадлежащих классам. Мне трудно перевести знания, переданные из этих вопросов, в мою проблему здесь.
Я занимаюсь классом, который я создал в прошлом для изучения, и я хотел бы иметь специализацию для арифметических типов.
template <typename T>
class Vector3
{
public:
T x;
T y;
T z;
public:
operator std::string() const;
}
Это специализация, которую я пытаюсь сделать:
template<typename T = std::enable_if<std::is_arithmetic<T>::value, T>::type>
inline Vector3<T>::operator std::string() const {
std::stringstream ss;
ss << "NOT NUMBER {" << x << ", " << y << ", " << z << "}";
return ss.str();
}
template<typename T = std::enable_if<!std::is_arithmetic<T>::value, T>::type>
inline Vector3<T>::operator std::string() const {
std::stringstream ss;
ss << "NUMBER {" << x << ", " << y << ", " << z << "}";
return ss.str();
}
Однако, когда я пытаюсь скомпилировать, я получаю
ошибка C2995: ‘Vector3::operator std::string(void) const’: шаблон функции уже определен
Когда я гуглю это, обычно это случаи, когда люди определили свой класс / метод в файле CPP, а также в файле заголовка. Поскольку я делаю это только в заголовочном файле, я могу только предположить, что enable_if неверен. Когда я смотрю на другие примеры, они просто специализируются на , , но я бы хотел использовать is_arithmitic способ.
Что я делаю не так? Заранее спасибо
Ответ №1:
Значение по умолчанию здесь:
template<typename T = XXX>
inline Vector3<T>::operator std::string() const { ... }
вообще не имеет значения, на данный момент вычет не выполняется и T
уже определен. Это законно, но это просто шум.
Теперь вы также не можете частично специализировать функцию-член в шаблоне класса, но мы можем использовать черты:
template <class T>
class Vector3 {
public:
// ...
operator std::string() const {
return as_string(std::is_arithmetic<T>{});
}
private:
std::string as_string(std::true_type ) {
// implementation for arithmetic types
}
std::string as_string(std::false_type ) {
// implementation for non-arithmetic types
}
};
Комментарии:
1. Спасибо за ответ. У меня было ощущение, что после всех поисков в Google мне придется использовать отправку тегов… Я посмотрю, есть ли у кого-нибудь другие идеи, прежде чем отмечать это как правильное.
Ответ №2:
Ответ Барри идеален.
Вот некоторые пояснения и предложения:
http://en.cppreference.com/w/cpp/types/enable_if
«Распространенной ошибкой является объявление двух шаблонов функций, которые отличаются только своими аргументами шаблона по умолчанию. Это незаконно, поскольку аргументы шаблона по умолчанию не являются частью подписи шаблона функции, и объявление двух разных шаблонов функций с одинаковой подписью является незаконным «.