Ale*_*lex 6 c++ type-traits c++-standard-library c++11
到目前为止我在网上找不到任何ELI5.对于学习项目,我想实现自己的is_constructible.有人可以解释它是如何工作的吗?
Que*_*tin 12
[I] f变量定义
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...>;
Run Code Online (Sandbox Code Playgroud)
该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,需要更高级的语言规则知识来制作表达,其有效性应该成为特征的价值.如果这证明在语言内部是不可行的,例如with std::is_standard_layout,那么编译器本身必须提供一个内部函数来检索值.