类方法的模板专业化。 “功能模板已定义”

时间:2016-10-05 16:36:31

标签: c++ templates template-specialization

我在方法的上下文中看到了许多关于特化的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':function   模板已经定义

当我谷歌这个时,通常情况下人们已经在CPP文件中定义了他们的类/方法以及头文件。由于我只在头文件中执行此操作,因此我只能假设enable_if不正确。当我查看其他示例时,他们只是专门研究,但我想使用is_arithmitic方式。

我做错了什么?提前致谢

2 个答案:

答案 0 :(得分:4)

此处的默认值为:

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 :(得分:1)

巴里的答案很完美。

以下是一些解释和建议:

http://en.cppreference.com/w/cpp/types/enable_if

“一个常见的错误是声明两个仅在默认模板参数上有所不同的函数模板。这是非法的,因为默认模板参数不是函数模板签名的一部分,并且声明具有相同签名的两个不同函数模板是非法的。 “