我写在C ++ 17类,我想超载转换操作符浮动类型,以及一些自定义类型。这里是重复的例子。还有更多的转换,我需要使用模板添加,但如果我能解决这些问题,剩下的应该是相似的。
class A {
};
class B : public A {
};
class C: public A {
};
class Missing {
public:
Missing() {}
Missing(Missing &) = default;
template<typename T,typename=typename std::enable_if_t<std::is_floating_point_v<T>, T>>
explicit constexpr operator T() const {
return static_cast<T>(NAN);
}
template<typename T, class = typename std::enable_if_t<std::is_base_of_v<A, T>, T>>
explicit operator T() const {
return T();
}
};
但是在用gcc编译8.2性病= C ++ 17的标志,我得到以下错误:
<source>:25:12: error: 'template<class T, class> Missing::operator T() const' cannot be overloaded with 'template<class T, class> constexpr Missing::operator T() const'
explicit operator T() const {
^~~~~~~~
<source>:20:22: note: previous declaration 'template<class T, class> constexpr Missing::operator T() const'
explicit constexpr operator T() const {
^~~~~~~~
Compiler returned: 1
我会认为,使用enable_if
将阻止运营商超载对于同一类型,但看起来像编译器是不是在看第一遍的enable_if
。我不知道我是否有正确的语法。任何帮助,将不胜感激。现在这已经有一段时间。
更新:
尝试更新的运营商
template<typename T>
constexpr explicit operator std::enable_if_t<std::is_floating_point_v<T>, T>() const {
return static_cast<T>(NAN);
}
template<typename T>
explicit operator std::enable_if_t<std::is_base_of_v<A, T>, T>() const {
return T();
}
但现在,在尝试投放该类浮动:
int main() {
Missing m;
float a = static_cast<float>(m);
}
我得到一个错误:
<source>:34:35: error: invalid static_cast from type 'Missing' to type 'float'
float a = static_cast<float>(m);
问题是,您声明相同的成员模板两次,用不同的默认参数。所以默认参数,甚至没有看任何实例之前的错误发生。
先冲来解决这将是移动enable_if_t
出论点并使其操作的返回类型:
template<typename T>
explicit constexpr operator std::enable_if_t<std::is_floating_point_v<T>, T>>() const ...
但是,这并不工作,因为T
是undeduced方面现在。
所以其他的方式,使两个模板不同的是添加一个虚拟参数有一个默认值其中之一。
template<typename T,
typename = std::enable_if_t<std::is_floating_point_v<T>, T>,
bool = true>
explicit constexpr operator T() const ...
其他模板应保持原样。
具有不同数量的模板参数的两个模板,他们不再认为是相同的。
另一种方法是定义导出模板参数是一个默认的指针:
template
<
typename T,
std::enable_if_t<std::is_floating_point_v<T>>* = nullptr
>
explicit constexpr operator T() const {
return static_cast<T>(NAN);
}
我觉得这是一个简洁,可靠的方式来选择是否启用方法,运营商和建设者。