【问题标题】:C++ - how is is_default_constructible implemented?C++ - is_default_constructible 是如何实现的?
【发布时间】:2017-09-09 21:17:13
【问题描述】:

您能否解释一下模板(例如 is_default_constructible 或 is_move_constructible)如何在类内部检查构造函数是否被标记为“默认”或是否为移动构造函数?

【问题讨论】:

  • 请注意,is_default_constructible 不会测试构造函数 = default 是否可以不带参数使用构造函数。它仍然可以由用户定义。

标签: c++ templates constructor


【解决方案1】:

is_default_constructible<T> 无法识别默认的 (= default) 默认构造函数。它主要辨别T()是否是有效的初始化(注意:不是T{})。

第一个近似值是:

template<typename T, typename = void>
struct is_default_constructible : std::false_type { };

template<typename T>
struct is_default_constructible<T, std::void_t<decltype(T())>> : std::true_type { };

标准版本中还有一些细微差别,因为例如void 不是默认可构造的,但void() 是一个有效的表达式。

【讨论】:

    【解决方案2】:

    您可以通过多种方式在编译时检查表达式的有效性。 detection idiom 是一种 C++11 技术,可用于实现您提到的特征。这是一个例子(这是一个近似值,实际的is_default_constructible更复杂)

    template <class T>
    using default_constructible_impl = decltype(T{});
    
    template <class T>
    using is_default_constructible = std::is_detected<default_constructible_impl, T>;
    

    这是我写的一篇文章,您可能会觉得有用:"checking expression validity in-place with C++17"。尽管它的标题暗示了什么,但它也涵盖了 C++11 和 C++14 技术。

    【讨论】:

    • 请注意,并非所有此类特征都可以以这种方式工作:std 库可以并且确实需要在没有“作弊”的情况下无法在 C++ 中实现的特征。而一些可以实现的traits,无论如何都可以通过作弊来实现(举个具体的例子,msvc作弊中的整数序列生成)。
    • 不,那不是is_default_constructible。而且没有std::is_detected_t
    猜你喜欢
    • 1970-01-01
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    • 2011-04-07
    • 2018-08-24
    • 1970-01-01
    • 2019-10-12
    相关资源
    最近更新 更多