std :: is_constructible< T,Args>实施? [英] How is std::is_constructible<T, Args> implemented?

查看:113
本文介绍了std :: is_constructible< T,Args>实施?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

到目前为止,我在网上找不到任何ELI5。对于一个学习项目,我想实现自己的is_constructible。

So far I can't find anything ELI5 online. For a learning project I would like to implement my own is_constructible. Can someone explain how it works, please?

推荐答案

来自 cppreference


[I] f变量定义 T obj(std :: declval< Args>()...); 格式正确,等于设为 true ,否则 value false

[I]f the variable definition T obj(std::declval<Args>()...); is well-formed, value is equal to true, else value is false.

可以使用SFINAE技术来检查代码是否格式正确,例如 void_t<< 技巧(预计将成为C ++ 1z标准库的一部分):

Checking whether code is well-formed can be done with SFINAE techniques, for example the void_t<> trick (expected to be part of the C++1z standard library):

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...>;

使用环向首先放置 void_t<> 参数。通常使用默认类型排在最后,但是该位置由可变的 Args 包保持。

The using hoop-hopping is there to place the void_t<> argument first. It usually comes last with a default type, but that position is held by the variadic Args pack.

is_constructible _ < void,T,Args ...> 实例化,编译器尝试首先实例化专门化。仅当 void_t< ...> 的内容在语义上有效,即 T(std :: declval< Args>( )...)可以正确执行-符合 is_constructible 的要求。请注意,我使用的是临时变量而不是局部变量,但据我所知,规则在两者之间没有变化。该专业化继承自 std :: true_type ,它产生 true value

When is_constructible_ is instantiated for <void, T, Args...>, the compiler tries to instantiate the specialization first. This only succeeds if the contents of void_t<...> are semantically valid, that is, T(std::declval<Args>()...) could be executed correctly -- as specified in the requirements of is_constructible. Note that I have used a temporary instead of a local variable, but to my knowledge the rules don't change between the two. The specialization inherits from std::true_type, which yields a true value.

如果无法实例化专业化(即 T(std :: declval< Args>()...)无效),则编译器会退回到常规模板,该模板始终可以实例化。这是从 std :: false_type 继承而来的,产生了 false value

If the specialization cannot be instantiated (i.e, T(std::declval<Args>()...) is not valid), the compiler falls back to the general template, which can always be instantiated. This one inherits from std::false_type, which yields the false value.

在Coliru上直播

更精确的特征,例如 std :: is_trivially_constructible ,需要更高级的语言规则知识拟定其有效性应成为特质价值的表达方式。如果从语言内部证明这是不可行的,例如使用 std :: is_standard_layout ,则编译器本身必须提供一个内部函数来检索值。

More precise traits, such as std::is_trivially_constructible, need more advanced knowledge of the language rules to craft the expression whose validity should become the value of the trait. If this proves infeasible from inside the language, such as with std::is_standard_layout, then the compiler itself has to provide an intrinsic function to retrieve the value.

这篇关于std :: is_constructible&lt; T,Args&gt;实施?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆