【问题标题】:Why doesn't C++ allow implicit list initialization in the conditional operator? [duplicate]为什么 C++ 不允许在条件运算符中进行隐式列表初始化? [复制]
【发布时间】:2019-10-02 01:16:19
【问题描述】:

这段代码编译:

std::string f(bool a, std::string const& b)
{
    if (a) return b;
    return {};
}

这段代码也可以编译:

std::string f(bool a, std::string const& b)
{
    return a ? b : std::string{};
}

此代码无法编译:

std::string f(bool a, std::string const& b)
{
    return a ? b : {};
}

鉴于?: 运算符的两个结果值都必须是相同的类型,为什么它不像第一个示例中那样推断类型?


看来这个问题可能与this 有类似的答案(基本上归结为“因为在编写语言规范时没有人考虑过它”)。但是我仍然认为保留这个问题是有用的,因为问题本身是不同的,它仍然足够令人惊讶,并且另一个不会出现在搜索这个问题。

【问题讨论】:

  • 两种类型都需要转换为相同的类型。 {} 没有类型。
  • clang 说 {} 是一个初始化列表(这里不能使用):godbolt.org/z/imYL6q
  • std::initializer_list<char>() 替换{} 也可以编译。
  • 也许这个问题可以变成语言提案
  • @miral:正确的术语是“列表初始化”。这就是标准所说的;你不会在标准中找到关于“统一初始化”的任何内容。

标签: c++ c++11 language-lawyer conditional-operator list-initialization


【解决方案1】:

花括号初始化器不是表达式,因此它没有类型。见:

https://scottmeyers.blogspot.com/2014/03/if-braced-initializers-have-no-type-why.html

花括号初始值设定项是一种语法结构,在标准中具有特殊规则,明确指定允许的使用和类型推导。正是因为大括号初始化器没有类型,所以需要这些特殊规则。未指定在 ?: 语句中使用它们,因此程序格式错误。

如果你真的需要听男人自己连续说三遍才相信,那么:

https://youtu.be/wQxj20X-tIU?t=1792

【讨论】:

  • return {}; 有效
  • @Miral "" 有一个类型。 std::initializer_list<char>{} 也有一个类型。 {} 没有。
  • @Miral: "它兼容任何类型" 不,不是。它是一种语法结构,在某些位置,可用于初始化类型的纯右值。它与任何东西都不“兼容”。
  • @NikosC.:应该注意,括号初始化列表没有类型,因为它们不是表达式。它们是与表达式不同的语法结构。因此,向他们询问类型就像询问他们的“价值”或与表达式相关的任何其他事情。
  • 我知道这不是编译器错误。但解释这个问题的另一种方式是“它作为一个要求真的有意义吗?”或“是否有技术原因无法完成?”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多