使用 enable_if 选择类构造函数
Select class constructor using enable_if
请考虑以下代码:
#include <iostream>
#include <type_traits>
template <typename T>
struct A {
int val = 0;
template <class = typename std::enable_if<T::value>::type>
A(int n) : val(n) {};
A(...) { }
/* ... */
};
struct YES { constexpr static bool value = true; };
struct NO { constexpr static bool value = false; };
int main() {
A<YES> y(10);
A<NO> n;
std::cout << "YES: " << y.val << std::endl
<< "NO: " << n.val << std::endl;
}
我想有选择地仅为某些使用 enable_if 的类型定义构造函数 A::A(int(。对于所有其他类型,有默认构造函数 A::A(...(,当替换失败时,它应该是编译器的默认情况。但是这对我来说很有意义 编译器(gcc 版本 4.9.0 20130714(仍在抱怨
sfinae.cpp:在"struct A"的实例化中:sfinae.cpp:19:11:
从这里需要 Sfinae.cpp:9:5:错误:中
没有名为"type"的类型 '结构标准::enable_if'
A(int n( : val(n( {};
构造函数可以这样的事情吗?使用另一个构造函数(复制构造函数和移动构造函数(是否可以做到这一点?
我认为这不适用于单个默认模板参数,因为它的值需要在实例化类模板时解析。
我们需要将替换推迟到构造函数模板实例化点。一种方法是将模板参数默认为 T,并向构造函数添加一个额外的虚拟参数:
template<typename U = T>
A(int n, typename std::enable_if<U::value>::type* = 0) : val(n) { }
with C++20
您只需向模板添加requires
即可实现这一点:
template <typename U = T> requires U::value
A(int n) : val(n) { }
requires
子句获取一个计算结果为 true
或false
从而决定是在重载解析中考虑此方法(如果 require 子句为 true(的constant expression
,否则忽略它。
代码:https://godbolt.org/z/CKTDFE
通常这是使用匿名默认参数完成的:
A(int n, typename std::enable_if<T::value>::type* = 0) : val(n) {};
不能将类中的模板参数用于 SFINAE out 方法。所以一种方法是添加一个虚拟类型替换 int :
请参阅: http://ideone.com/2Gnyzj
#include <iostream>
#include <type_traits>
template <typename T>
struct A {
int val = 0;
template<typename Integer
,typename = typename std::enable_if<T::value && sizeof(Integer)>::type
>
A(Integer n) : val(n) {};
A(...) {}
/* ... */
};
struct YES { constexpr static bool value = true; };
struct NO { constexpr static bool value = false; };
int main() {
A<YES> y(10);
A<NO> n;
std::cout << "YES: " << y.val << std::endl
<< "NO: " << n.val << std::endl;
}
这是有效的,因为您使用成员模板参数来 SFINAE 输出构造函数,但测试始终为真,因此它不会污染您的检查
- 选择要调用的构造函数
- C++ 带有默认参数的结构,可选择在构造函数中更改
- C++:使用委托构造函数时选择"const char *"与"std::string&qu
- 为什么Visual Studio无法在模板类中选择正确的构造函数
- 如何根据 C++ 中的 cv 限定符选择构造函数
- 编译如何选择要拨打的构造函数
- 编译时构造函数选择
- Clang 和 GCC 在使用大括号表示法和initializer_list时在构造函数选择上存在分歧
- 未选择引用到数组的构造函数进行列表初始化
- 使用 std::function 时选择自动返回类型而不是构造函数的调用运算符
- 我是否应该使用功能指针在构造函数中选择实现
- 无法选择模板构造函数
- C++:如何根据条件选择构造函数
- 为什么选择复制构造函数而不是移动构造函数
- 编译器在移动和复制构造函数之间的选择
- RAII 在两个构造函数之间进行选择的方式
- 如何选择构造函数模板
- 当参数是引用时,可变模板构造函数选择失败
- 如何消除构造函数选择的强制转换
- 是否有可能编写一个抽象类,其中构造函数选择适当的子类在c++中实例化