到目前为止,我无法在线找到任何ELI5。对于学习项目,我想实现自己的is_constructible。有人可以解释它是如何工作的吗?
答案 0 :(得分:11)
来自cppreference:
[我]变量定义
T obj(std::declval<Args>()...);
格式正确,value
等于true
,否则value
为false
。
检查代码是否格式良好可以使用SFINAE技术完成,例如void_t<>
技巧(预计将成为C ++ 1z标准库的一部分):
template <class...>
using void_t = void;
template <class, class T, class... Args>
struct is_constructible_ : std::false_type {};
template <class T, class... Args>
struct is_constructible_<
void_t<decltype(T(std::declval<Args>()...))>,
T, Args...> : std::true_type {};
template <class T, class... Args>
using is_constructible = is_constructible_<void_t<>, T, Args...>;
using
箍跳是首先放置void_t<>
参数。它通常是最后一个默认类型,但该位置由可变参数Args
包保存。
当为is_constructible_
实例化<void, T, Args...>
时,编译器会首先尝试实例化特化。只有void_t<...>
的内容在语义上有效时才会成功,即T(std::declval<Args>()...)
可以正确执行 - 正如is_constructible
的要求中所指定的那样。请注意,我使用的是临时变量而不是局部变量,但据我所知,规则在两者之间不会发生变化。专精化继承自std::true_type
,产生true
value
。
如果无法实例化特化(即T(std::declval<Args>()...)
无效),编译器将回退到通用模板,该模板始终可以实例化。这一个继承自std::false_type
,产生false
value
。
更精确的特征,例如std::is_trivially_constructible
,需要更高级的语言规则知识来制作表达,其有效性应该成为特征的价值。如果这证明在语言内部是不可行的,例如使用std::is_standard_layout
,那么编译器本身必须提供一个内部函数来检索值。