【发布时间】:2019-02-05 04:09:53
【问题描述】:
我正在用 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();
}
};
但是,在使用带有 std=c++17 标志的 gcc 8.2 进行编译时,我收到以下错误:
<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移出参数并使其成为运算符的返回类型。 -
我更新了模板,但现在我得到了无效的 static_cast。我会用我尝试过的方法更新问题。
-
Aww 抱歉,您不能这样做,这会创建一个未推断的上下文。我会用另一种方法来回答。
标签: c++ templates c++17 sfinae