【问题标题】:std::is_constructible doesn't give the correct result [duplicate]std::is_constructible 没有给出正确的结果[重复]
【发布时间】:2016-05-02 05:14:20
【问题描述】:

源自thisCodeReview话题:

#include <cstddef>
#include <algorithm>
#include <iostream>
#include <type_traits>
#include <utility>

template <typename T>
class aggregate_wrapper : public T {
private:
  using base = T;

public:
  using aggregate_type = T;

  template <typename... Ts>
  aggregate_wrapper(Ts&&... xs)
      : base{std::forward<Ts>(xs)...} {
    // nop
  }
};

struct foo_t {
  foo_t(int) {}  
};

int main() {
  std::cout << std::is_constructible<foo_t>::value << std::endl;
  std::cout << std::is_constructible<aggregate_wrapper<foo_t>>::value << std::endl;
  // aggregate_wrapper<foo_t> v; // won't compile
}

aggregate_wrapper&lt;foo_t&gt; v; 没有实际编译时,std::is_constructible&lt;aggregate_wrapper&lt;foo_t&gt;&gt;::value 怎么可能是真的?

【问题讨论】:

  • 也许您在心理上将 constructibledefaultconstructible 混为一谈? aggregate_wrapper&lt;foo_t&gt; 当然可以构造,只是不能通过aggregate_wrapper&lt;foo_t&gt; v; 构造。
  • @M.M Nope、is_default_constructible&lt;T&gt;is_constructible&lt;T&gt;(这意味着 Args... 是一个空包)是等价的。
  • 不确定为什么重新打开; dup 直接在点上。
  • @T.C. : 纯属意外!

标签: c++ language-lawyer c++14 template-meta-programming typetraits


【解决方案1】:

在 C++ 标准中,在 is_constructible 描述中,有这样看似无辜的引用:

仅考虑 [imaginary v] 变量初始化的即时上下文的有效性。

然后是解释其含义的注释:

初始化的评估可以导致边 例如类模板特化和函数模板特化的实例化, 生成隐式定义的函数,等等。此类副作用不在即时上下文中,并可能导致程序格式错误。

我的解释是当你写的时候:

aggregate_wrapper<foo_t> v;

您正在使用aggregate_wrapper 的默认构造函数,它存在并且可以访问,所以它成功了,至少在即时上下文中是这样。然后,非立即上下文包括构造函数的主体,这会失败,但不会改变 is_constructible 的结果。

【讨论】:

  • 那么我猜std::is_constructible 无论如何也没那么有用。宁愿自己写一个超越当前上下文的。
  • 真正的问题应该是为什么std::is_constructible 停在immediate context
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-01
相关资源
最近更新 更多