c – 每当成员变量可以由可变参数构造时,有条件地启用构造函数
发布时间:2020-12-16 07:16:13 所属栏目:百科 来源:网络整理
导读:我有一个带有模板参数Tuple的类foo,我想提供一个可变参数构造函数来初始化类型为Tuple的成员变量m_elements,每当表达式m_elements {static_cast typename Tuple :: value_type(std :: forward Elements(元素))…}被定义. 我们可以通过以下方式执行此操作: t
我有一个带有模板参数Tuple的类foo,我想提供一个可变参数构造函数来初始化类型为Tuple的成员变量m_elements,每当表达式m_elements {static_cast< typename Tuple :: value_type>(std :: forward< Elements>(元素))…}被定义.
我们可以通过以下方式执行此操作: template<class Tuple> struct foo { using value_type = typename Tuple::value_type; template<class... Elements,class U = Tuple,class = decltype(U{ static_cast<value_type>(std::declval<Elements>())... })> foo(Elements&&... elements) : m_elements{ static_cast<value_type>(std::forward<Elements>(elements))... } {} Tuple m_elements; }; 现在,是否启用此构造函数还应取决于其他一些条件.所以,我需要写一些类似的东西 template<class... Elements,class = std::enable_if_t</* some other conditions depending on U */>,class = decltype(U{ static_cast<value_type>(std::declval<Elements>())... })> 我想用std :: is_constructible检查我的第一个条件,这样我就可以将这个检查移动到enable_if中.这可能吗?我试过使用std :: is_constructible_v< U,decltype(static_cast< value_type>(std :: declval< Elements>()))…>,但这似乎不等同于之前的检查. 例如,foo< bar< 3>> {1,2,3};同 template<std::size_t N> struct bar { using value_type = double; double data[N]; }; 将使用上一个检查进行编译,但会产生新错误. 解决方法
如
Rostislav所述,如果T不是函数类型,则std :: is_constructible_v< T,Args>如果变量定义为T obj(std :: declval< Args>()…);则为真;结构良好.条形码< 1>中的情况并非如此. obj(0.);,导致条< 1>没有相应的构造函数.
相反,bar1< 1> obj {0.};结构良好.使用建议的Detection Toolkit,我们可以使用 template<class T,typename... Arguments> using initializable_t = decltype(T{ std::declval<Arguments>()... }); template<class T,typename... Arguments> constexpr bool is_initializable_v = is_detected_v<initializable_t,T,Arguments...>; 并将支票更改为 template<class... Elements,class = std::enable_if_t<is_initializable_v<U,decltype(static_cast<value_type>(std::declval<Elements>()))...>>> 我认为这比普通的decltype方法更具可读性. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |