【问题标题】:Why Implementation for is_copy_assignable doesn't work?为什么 is_copy_assignable 的实现不起作用?
【发布时间】:2018-09-20 23:34:21
【问题描述】:

这是我对 is_copy_assignable 实现的尝试:

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

template<typename T>
struct IsCopyAssignable<T, decltype(std::add_lvalue_reference<T>::type = std::add_lvalue_reference<const T>::type, void())> : std::true_type
{};

这是一个失败。

这是测试用例:

int main()
{
    struct Structure {};
    std::cout << "IsCopyAssignable=\n";
    std::cout << IsCopyAssignable<int>::value << '\n'; // should be true
    std::cout << IsCopyAssignable<int&>::value << '\n'; // should be true
    std::cout << IsCopyAssignable<const int&>::value << '\n'; // should be false
    std::cout << IsCopyAssignable<const double&>::value << '\n'; // should be false
    std::cout << IsCopyAssignable<class Structure>::value << '\n'; // should be true
    std::cout << '\n';
}

它们都打印错误。

(然后我意识到 declval 与方便的 void_t - 当然还有 decltype - 可以用于类似的事情。)但我仍然不明白为什么这个不起作用。我想我们想测试是否可以将const T&amp; 分配给T&amp;(就像复制分配运算符一样)。那么,为什么呢?

【问题讨论】:

  • int&amp; = const int&amp; 没有任何意义。可能你想把std::declval&lt;typename std::add_lvalue_reference&lt;T&gt;::type&gt;() 等放在那里。
  • @DanielSchepler 这就是答案。基本上,您注意到的是,专业化总是 SFINAE 消失,因为它没有意义。
  • 从技术上讲,如果您进行了诸如 template&lt;&gt; struct std::add_lvalue_reference&lt;Structure&gt; { static bool type; }; 之类的专业化处理,您也许可以使 IsCopyAssignable&lt;Structure&gt;::value 为真,std::add_lvalue_reference&lt;const Structure&gt; 也同样如此 - 尽管标准自然也会使这种未定义的行为...跨度>

标签: c++ templates template-meta-programming sfinae copy-assignment


【解决方案1】:

您的decltype(std::add_lvalue_reference&lt;T&gt;::type = std::add_lvalue_reference&lt;const T&gt;::type, void()) 对于每个T 都是错误的,因为std::add_lvalue_reference&lt;T&gt;::type 实际上不是一个值,而是一个类型。

std::declval 可能会有所帮助:

您想改为检查表达式 std::declval&lt;T&amp;&gt;() = std::declval&lt;const T&amp;&gt;() 是否有效。

所以

template<typename T>
struct IsCopyAssignable<T,
                       decltype(std::declval<T&>() = std::declval<const T&>(), void())>
       : std::true_type
{};

【讨论】:

  • 是的。但是,我们不应该处理在 decltype 的“未评估上下文”中创建的表达式中的类型而不是值吗?
  • decltype 返回给定表达式的类型,值用于表达式,而不是类型。 i = 42int&amp; = int.
猜你喜欢
  • 1970-01-01
  • 2022-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-14
  • 1970-01-01
  • 2011-01-12
相关资源
最近更新 更多