【问题标题】:How to check if type is explicitly/implicitly constructible?如何检查类型是否显式/隐式可构造?
【发布时间】:2017-03-14 12:52:21
【问题描述】:

如何检查某些类型是否可以从其他类型显式(反之亦然)构造?在这种情况下有什么 SFINAE 技巧吗?

我可以把is_explicitly_constructible写成combination of std::is_constructible and std::is_convertible

#include <type_traits>

template <typename Type, typename Argument>
struct is_explicitly_constructible
    : std::bool_constant
        <
            std::is_constructible<Type, Argument>::value &&
            !std::is_convertible<Argument, Type>::value
        >
{
};

但我是否考虑到此类代码中的所有可能情况?

【问题讨论】:

  • 在我看来,将declvalstatic_cast 结合起来应该确定一种类型是否可以从另一种类型转换。将其与典型的 SFINAE 测试相结合,应该可以解决问题。
  • 问题只是:这是正确的吗?如果是这样,是的。
  • @SamVarshavchik 但我想检查一种类型是否 constructible 来自另一种类型,而不是 convertible。而static_cast 支持转换非类本身的类型。
  • @Barry 这里没有陷阱吗?像竞争的构造函数或其他东西......
  • @Constructor std::is_constructible&lt;X,Y&gt; 做正确的事。它不检查构造函数 X(Y ) 是否存在 - 只检查假设的 X x(y); 是否格式正确。

标签: c++ sfinae c++17 typetraits explicit


【解决方案1】:

是的,这是正确的。如果

  1. 它完全可以从A 构造。也就是说,假设的T x(a) 是有效的。
  2. 隐式转换格式不正确。也就是说,假设函数T test() { return a; } 的格式不正确。

std::is_constructible 测试#1,std::is_convertible 测试#2 的有效性。因此,想要 #1 而不是 #2 将是 is_explicitly_constructible,就像 #1 和 #2 将是 is_implicitly_constructible


这样的is_explicitly_constructible/is_implicitly_constructible 对是您将如何实现一个有条件地为explicit 的构造函数。例如,在 libstdc++ 中,optional 的这两个构造函数存在:

implicit:

 template <typename _Up = _Tp,
            enable_if_t<__and_<
              __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
              is_constructible<_Tp, _Up&&>,   // (*) 
              is_convertible<_Up&&, _Tp>      // (*)
              >::value, bool> = true>
  constexpr optional(_Up&& __t)

explicit:

  template <typename _Up = _Tp,
            enable_if_t<__and_<
              __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
              is_constructible<_Tp, _Up&&>,        // (*)
              __not_<is_convertible<_Up&&, _Tp>>   // (*)
              >::value, bool> = false>
  explicit constexpr optional(_Up&& __t);

您可以看到 libstdc++ 使用与您相同的表达式。

【讨论】:

  • 感谢您如此详细的回答! is_explicitly_convertible/is_implicitly_convertible呢?
  • @Constructor 嗯?
  • is_implictly_convertible == is_convertible &amp;&amp; !is_explicitly_convertible, is_explicitly_convertible == ?
  • 没有隐式与显式可转换。有敞篷车,这意味着隐含的。
  • @Constructor 我猜你要找的是is_explicitly_convertible&lt;From,To&gt;std::is_constructible&lt;To,From&gt;is_implicitly_convertible&lt;From,To&gt;std::is_convertible&lt;From,To&gt;
猜你喜欢
  • 1970-01-01
  • 2013-05-29
  • 1970-01-01
  • 2016-02-29
  • 1970-01-01
  • 1970-01-01
  • 2013-11-09
  • 2011-10-15
  • 2023-04-02
相关资源
最近更新 更多