SFINAE 构造函数
SFINAE Constructors
我一直喜欢这样的 SFINAE 函数语法,似乎总体上运行良好!
template <class Integer, class = typename std::enable_if<std::is_integral<Integer>::value>::type>
T(Integer n) {
// ...
}
但是 运行 当我想在同一个 class...
中执行此操作时遇到了问题
template <class Float, class = typename std::enable_if<std::is_floating_point<Float>::value>::type>
T(Float n) {
// ...
}
出现这样的错误:
./../T.h:286:2: error: constructor cannot be redeclared
T(Float n) {
^
./../T.h:281:2: note: previous definition is here
T(Integer n) {
^
1 error generated.
这些构造函数不应该只存在于适当的类型中,并且永远不会同时存在吗?他们为什么会冲突?
我是不是有点厚了?
另一方面这确实有效(但我不太喜欢这种语法):
template <class Integer>
T(Integer n, typename std::enable_if<std::is_integral<Integer>::value>::type* = nullptr) {
}
template <class Float>
T(Float n, typename std::enable_if<std::is_floating_point<Float>::value>::type* = nullptr) {
}
改为使用非类型模板参数:
template <class Integer,
std::enable_if_t<std::is_integral<Integer>::value, int> = 0>
T(Integer n) {
// ...
}
template <class Float,
std::enable_if_t<std::is_floating_point<Float>::value, int> = 0>
T(Float n) {
// ...
}
这是可行的,因为编译器必须先替换第一个模板参数,然后才能确定值参数的类型。
解决此问题的一种方法是添加额外的 , typename=void
个参数,以便 none 个重载具有相同数量的模板参数。
我一直喜欢这样的 SFINAE 函数语法,似乎总体上运行良好!
template <class Integer, class = typename std::enable_if<std::is_integral<Integer>::value>::type>
T(Integer n) {
// ...
}
但是 运行 当我想在同一个 class...
中执行此操作时遇到了问题template <class Float, class = typename std::enable_if<std::is_floating_point<Float>::value>::type>
T(Float n) {
// ...
}
出现这样的错误:
./../T.h:286:2: error: constructor cannot be redeclared
T(Float n) {
^
./../T.h:281:2: note: previous definition is here
T(Integer n) {
^
1 error generated.
这些构造函数不应该只存在于适当的类型中,并且永远不会同时存在吗?他们为什么会冲突?
我是不是有点厚了?
另一方面这确实有效(但我不太喜欢这种语法):
template <class Integer>
T(Integer n, typename std::enable_if<std::is_integral<Integer>::value>::type* = nullptr) {
}
template <class Float>
T(Float n, typename std::enable_if<std::is_floating_point<Float>::value>::type* = nullptr) {
}
改为使用非类型模板参数:
template <class Integer,
std::enable_if_t<std::is_integral<Integer>::value, int> = 0>
T(Integer n) {
// ...
}
template <class Float,
std::enable_if_t<std::is_floating_point<Float>::value, int> = 0>
T(Float n) {
// ...
}
这是可行的,因为编译器必须先替换第一个模板参数,然后才能确定值参数的类型。
解决此问题的一种方法是添加额外的 , typename=void
个参数,以便 none 个重载具有相同数量的模板参数。