【问题标题】:C++ ternary operators, Any difference?C++ 三元运算符,有什么区别吗?
【发布时间】:2020-09-12 00:22:10
【问题描述】:

我正在阅读以下内容的区别:

1)

std::string test = level > 10 ? "Master" : "Beginner";

2)

std::string test;
if (level > 10)
    test = "Master";
else
    test = "Beginner";

在第二种情况下,有人告诉我,在第二种选择中,正在创建一个我不理解的临时值。

我了解到,当我们声明一个没有初始化的变量时,它会占用垃圾,所以编译器只保存一个内存位置,并不能“工作”来改变它的值。

【问题讨论】:

  • 这能回答你的问题吗? Ternary operator ?: vs if...else
  • 您的示例中没有“垃圾”,std::string 有一个被调用的构造函数。严格来说,一般来说,统一化的东西的价值不是“垃圾”,只是不允许你使用它,如果你这样做了,你会得到一些看起来像垃圾的东西

标签: c++ initialization conditional-operator


【解决方案1】:

在语法上,第一种情况有点等价于:

constexpr const char* f(int level) {
    if (level > 10)
        return "Master";
    else
        return "Beginner";
}

std::string test = f(level);

这里,test 立即用"Master""Beginner" 初始化。在第二种情况下,test 首先被默认初始化,然后分配给它。

但是,优化后不一定是这样:编译器可以很好地在两种情况下生成完全相同的代码。

当我们声明一个没有初始化的变量时,它会产生垃圾

这仅适用于基本类型和 POD 类型,而不是像 std::string 这样具有默认构造函数的类。详情请查看default-initialization

【讨论】:

  • “但是,优化后不一定是这样:编译器可以很好地在两种情况下生成完全相同的代码” - 在用户定义副本的一般情况下c'tor 和赋值运算符,编译器无法证明这两个调用的含义完全相同,因此很可能不会生成相同的代码。
【解决方案2】:

在这两种情况下都没有构造临时对象。

在第一种情况下,test 是由三元运算符直接返回的const char* 中的copy-initialized,通过std::string 的构造函数取const char*

在第二种情况下,test 首先是default-initialized,然后通过std::string 的赋值运算符从ifelse 分支中的const char* 分配。 (顺便说一句:默认初始化后test 不会接受垃圾,它会被std::string 的默认构造函数初始化为空字符串。)

【讨论】:

  • 但是当我访问它时,我得到了奇怪的值
  • @smith_brown 我试过here 并且似乎工作正常。你是什​​么意思得到奇怪的值?你能给它一个Minimal, Reproducible Example吗?
【解决方案3】:

没有理由不使用第一种形式,但是如果编译器没有为任何一种生成相同的代码,就会出现严重的性能问题。话虽如此,第一种形式清晰易懂,可能会减少优化器的工作量,因此您不妨使用它。它清楚地说明了将变量初始化为两个给定值之一的意图,并且最清楚地表达意图的代码通常会生成最好的生成代码(并且最容易理解)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-20
    • 2018-12-05
    • 1970-01-01
    • 1970-01-01
    • 2019-07-09
    • 1970-01-01
    • 2011-10-09
    • 1970-01-01
    相关资源
    最近更新 更多