构造函数有条件标记为显式 [英] Constructor conditionally marked explicit
问题描述
更新:条件显式 已纳入C ++ 20草案。 有关cppreference的更多信息
Update: conditional explicit has made it into the C++20 draft. more on cppreference
cppreference std :: tuple构造器页面具有许多C + +17注释表明诸如此类的内容:
The cppreference std::tuple constructor page has a bunch of C++17 notes saying things like:
此构造函数在以下情况下为
explicit
:std :: is_convertible< const Ti& ;, Ti> :: value
对于至少一个i
This constructor is
explicit
if and only ifstd::is_convertible<const Ti&, Ti>::value
is false for at least onei
如何编写有条件显式的构造函数?我想到的第一种可能性是 explicit(true)
,但这不是合法的语法。
How can one write a constructor that is conditionally explicit? The first possibility that came to mind was explicit(true)
but that's not legal syntax.
尝试使用 enable_if
不成功:
// constructor is explicit if T is not integral
struct S {
template <typename T,
typename = typename std::enable_if<std::is_integral<T>::value>::type>
S(T) {}
template <typename T,
typename = typename std::enable_if<!std::is_integral<T>::value>::type>
explicit S(T) {}
};
,但出现错误:
error: ‘template<class T, class> S::S(T)’ cannot be overloaded
explicit S(T t) {}
推荐答案
添加了 N4387:改进对和元组,修订版3 给出了其工作方式示例:
The proposal that added that N4387: Improving pair and tuple, revision 3 has an example of how it works:
考虑下面的类模板A,该类模板打算将
用作其他某些类型T的包装:
Consider the following class template A that is intended to be used as a wrapper for some other type T:
#include <type_traits>
#include <utility>
template<class T>
struct A {
template<class U,
typename std::enable_if<
std::is_constructible<T, U>::value &&
std::is_convertible<U, T>::value
, bool>::type = false
>
A(U&& u) : t(std::forward<U>(u)) {}
template<class U,
typename std::enable_if<
std::is_constructible<T, U>::value &&
!std::is_convertible<U, T>::value
, bool>::type = false
>
explicit A(U&& u) : t(std::forward<U>(u)) {}
T t;
};
所示的构造函数均使用完美转发,并且除了一个签名外,它们具有相同的签名。是明确的,其他
则不是。此外,它们相互排斥地受约束。
换句话说:此组合对于任何目标类型T
和任何参数类型U都起作用,例如单个构造函数,即
显式或非显式(或根本没有构造函数)。 / p>
The shown constructors both use perfect forwarding and they have essentially the same signatures except for one being explicit, the other one not. Furthermore, they are mutually exclusively constrained. In other words: This combination behaves for any destination type T and any argument type U like a single constructor that is either explicit or non-explicit (or no constructor at all).
正如Praetorian指出的,这正是 libstdc ++实现了。
As Praetorian points out this is exactly how libstdc++ implements it.
如果我们相应地修改OP示例,它也可以工作:
If we modify the OPs example accordingly, it also works:
struct S {
template <typename T,
typename std::enable_if< std::is_integral<T>::value, bool>::type = false>
S(T) {}
template <typename T,
typename std::enable_if<!std::is_integral<T>::value, bool>::type = false>
explicit S(T) {}
};
这篇关于构造函数有条件标记为显式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!