【问题标题】:Conditional ? : operator with class constructor有条件的? : 带有类构造函数的运算符
【发布时间】:2019-04-26 04:12:21
【问题描述】:

有人可以解释一下为什么cc1 的构造方式不同。 我了解我参考了由“?”创建的副本运算符,在构造后被销毁,但为什么在第一种情况下它的行为方式不同。 我测试了它是否优化,但即使从控制台读取条件,我也有相同的结果。提前致谢

#include <vector>

class foo {
public:
    foo(const std::vector<int>& var) :var{ var } {};
    const std::vector<int> & var;
};

std::vector<int> f(){
    std::vector<int> x{ 1,2,3,4,5 };
    return x;
};

int main(){
    std::vector<int> x1{ 1,2,3,4,5 ,7 };
    std::vector<int> x2{ 1,2,3,4,5 ,6 };
    foo c{ true ? x2 : x1 };    //c.var has expected values 
    foo c1{ true ? x2 : f() };  //c.var empty 
    foo c2{ false ? x2 : f() };  //c.var empty 
    foo c3{ x2 };  //c.var has expected values
}

【问题讨论】:

    标签: c++ c++14 conditional-operator


    【解决方案1】:

    条件表达式的类型是两个分支的公共类型,它的值类别也依赖于它们。

    • 对于true ? x2 : x1普通类型std::vector&lt;int&gt;值类别左值。这可以通过以下方式进行测试:

      static_assert(std::is_same_v<decltype((true ? x2 : x1)),  std::vector<int>&>); 
      
    • 对于true ? x2 : f()常用类型std::vector&lt;int&gt;值类别prvalue。这可以通过以下方式进行测试:

      static_assert(std::is_same_v<decltype((true ? x2 : f())),  std::vector<int>>); 
      

    因此,您在c1 中存储了一个悬空引用。对c1.var 的任何访问都是未定义行为

    live example on godbolt.org

    【讨论】:

    • ...导致UB,if声明后访问。不过,OP 的示例中省略了该关键部分。
    • 最好解释一下为什么这些是常见类型(即:因为第二种情况涉及一个左值和纯右值,而第一种情况是两个左值)。
    • 哦,C++。哦你。
    • 不要将表达式的类型与其值类别混为一谈。 ?: 从来没有引用类型。甚至不是在进行任何进一步分析之前调整过的那个。
    • @T.C.:更新了答案,如果现在正确请告诉我。
    猜你喜欢
    • 1970-01-01
    • 2019-09-26
    • 1970-01-01
    • 2023-03-31
    • 2011-04-28
    • 1970-01-01
    • 2011-05-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多