我一直在尝试创建模板化类方法的特化,这样我就会有不同的方法定义,编译器根据参数是否为枚举类的整型选择,但是clang给了我这个错误:
'ParseString'的越行定义与'MyData'中的任何声明不匹配
而GCC给出如下:
下面的代码用于产生这些错误。我已经尝试了使用错误:原型'typename std::enable_if::value, void>::type MyData::ParseString(T&, std::string)'不匹配任何类'MyData'
错误:候选人是:模板静态无效MyData::ParseString(T&, std::string)
enable_if
的其他方法,比如在模板参数中而不是返回类型中,但到目前为止都没有效果。如果我将模板化的函数设置为非类函数而不是类方法,那么它们就可以正常工作。(去除静电没有影响)
是否有一种方法可以使用enable_if
模板化类方法,或者更好的方法来实现同样的事情?
#include <string>
#include <type_traits>
#include <utility>
class MyData
{
public:
MyData() = default;
MyData(std::pair<std::string, std::string> string_representations);
std::pair<std::string, std::string> ToStrings();
enum class MyEnum
{
A = 0,
B = 1
};
int integral_value;
MyEnum enum_value;
private:
template<typename T>
static void ParseString(T&, std::string);
};
MyData::MyData(std::pair<std::string, std::string> string_representations)
{
ParseString(integral_value, string_representations.first);
ParseString(enum_value, string_representations.second);
}
std::pair<std::string, std::string> MyData::ToStrings()
{
return std::make_pair(std::to_string(integral_value), std::to_string((unsigned long)enum_value));
}
template<typename T>
typename std::enable_if<std::is_enum<T>::value, void>::type
MyData::ParseString(T& setting, std::string representation)
{
setting = (T)std::stoul(representation);
}
template<typename T>
typename std::enable_if<std::is_integral<T>::value, void>::type
MyData::ParseString(T& setting, std::string representation)
{
setting = std::stoi(representation);
}
(在本例中,该类只有一个整型和一个枚举成员,但如果您想知道为什么模板化函数会有用,请想象一下,如果该类有多个不同的枚举和整型成员。)
这个错误告诉你,你的ParseString
方法定义中的签名不匹配类内部声明中的签名。您必须复制enable_if
并在声明中使用它。
template<typename T>
static typename std::enable_if<std::is_integral<T>::value, void>::type ParseString(T&, std::string);
您还需要另一个在声明中使用enable_if<is_enum<T>>
的ParseString
声明,因为您定义了另一个使用它的函数:
template<typename T>
static typename std::enable_if<std::is_enum<T>::value, void>::type ParseString(T&, std::string);