何时允许推导initializer_list?

4

我知道有一些特殊规则可以推断初始化列表,但在发现以下内容之前,我认为从来没有这种情况。什么情况下可以推断或省略initializer_list

以下示例似乎不合逻辑,几乎感觉像语言缺陷?

#include <initializer_list>

void test() {
    bool reverse = true;
    const auto ascend = {1,2,3};//OK : seems to deduce to std::initializer_list<const int>

    //const auto a_or_d_AUTO = reverse ? {3,2,1} : {1,2,3};//not ok, why ?

    const auto i = reverse ? 3 : 1;// also fine

    const auto a_or_d = reverse ? std::initializer_list<const int>({3,2,1}) : std::initializer_list<const int>({1,2,3});//also OK
}

https://godbolt.org/z/1sNcu4

1个回答

12

这与推导无关。条件运算符?:的语法要求所有三个操作数都是实际表达式:

[expr.cond]

conditional-expression:
    logical-or-expression
    logical-or-expression ? expression : assignment-expression

大括号初始化列表不是表达式,因此不能与?:一起使用。


2
虽然你的回答并不是错误的,但非常简略——考虑到将来会来到这里的用户。请例如更新你的回答,解释为什么 const auto ascend = {1,2,3}; 虽然 {1,2,3} 不是一个表达式也可以正常工作?此外,值得一提的是,它不是一个表达式的唯一原因是委员会决定放弃了它,如果有的话,将来可能有哪些可能性发生改变。谢谢。 - darune
4
@darune 你不能期望每个试图帮助你的人都给你写一篇百科全书式的文章。看起来你对这个主题比你表现出的更了解,或者至少你知道该寻找什么。回答简洁明了,清晰明了。用标准化语言和关于委员会正在发生什么情况的“今天”类声明来扩展它将使它变得混乱,并降低其整体实用性。如果你想知道那些内容,请提一个不同的问题。 - rubenvb
4
更重要的是,你在这个问题上贴了“language-lawyer”标签。你得到了一个语言律师的回答(确实如此)。T.C. 是某种专家。 - jonspaceharper
标准的引用部分为[expr.cond/7.6.16]braced-init-list是一个声明,而不是表达式(请参见[dlc.init/9.3][dcl.init.list/9.3.4])。 - jonspaceharper
2
@JonHarper 花括号初始化列表 不是一个声明。我想你可以称它为一个初始化器。 - Rakete1111

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接