【问题标题】:Fold expressions and parameter pack: difference betwen Args&& and Args inside static_assert折叠表达式和参数包:静态断言中的 Args&& 和 Args 之间的区别
【发布时间】:2019-10-15 22:32:31
【问题描述】:

此代码来自
https://en.cppreference.com/w/cpp/language/fold

template<typename T, typename... Args>
void push_back_vec(std::vector<T>& v, Args&&... args){
    static_assert((std::is_constructible_v<T, Args&&> && ...));
    (v.push_back(std::forward<Args>(args)), ...);
}

我不明白为什么静态断言检查 Args&amp;&amp; 而不是 Args

【问题讨论】:

  • 你好像打错了:checks for Args&amp;&amp; and not for Args&amp;&amp;
  • 两种形式似乎编译和执行相同,除非我遗漏了什么。
  • 是的,我的想法正是……

标签: c++ c++17 fold-expression


【解决方案1】:

这适用于像这样的极端情况,当您只有类型声明但没有定义时(std::is_constructible on incomplete types - 在这种情况下 is_constructible 是 UB ):

struct B;

struct A {
    A(const A&) = default;
    A(const B&) {}

    A(A&&) = default;
    A() = default;
};
B&& getB();

template<typename T, typename... Args>
void push_back_vec(std::vector<T>& v, Args&&... args){
    static_assert((std::is_constructible_v<T, Args&&> && ...));
    (v.push_back(std::forward<Args>(args)), ...);
}

template<typename T, typename... Args>
void push_back_vec2(std::vector<T>& v, Args&&... args){
    static_assert((std::is_constructible_v<T, Args> && ...));
    (v.push_back(std::forward<Args>(args)), ...);
}

int main(int argc, char* argv[])
{
    std::vector<A> a;

    push_back_vec(a, A(), A());
    push_back_vec2(a, A(), A());

    A aa;
    push_back_vec(a, aa, aa, A());
    push_back_vec2(a, aa, aa, A());


    push_back_vec(a, getB());
    // code below won't compile
    //push_back_vec2(a, aa, A(), getB());
}

Live example

【讨论】:

  • "下面的代码不会编译" 但是push_back_vec(a, getB()); 也不会编译。这两行都给了我undefined reference to 'getB'。我错过了什么吗?
  • @HolyBlackCat 对我来说编译得很好:godbolt.org/z/TVM3Ap。当然,不会链接,但那是另一回事。
  • 嗯。 Clang 确实抱怨 push_back_vec2(a, aa, A(), getB());,但 GCC 没有。
  • @HolyBlackCat 正如我所说,UB。 Clang 在这里对故障的检测更加严格。恕我直言,如果这很容易,这应该是标准的,但那是另一回事。看到这个:stackoverflow.com/questions/55831521/…
猜你喜欢
  • 1970-01-01
  • 2011-08-25
  • 2021-01-30
  • 2013-09-16
  • 2021-07-29
  • 1970-01-01
  • 2015-09-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多