C++1z 在自动函数中使用 std::initializer_list<int> 和 w/o const 处理 == 测试

C++1z handling of a == test with std::initializer_list<int> with and w/o const in an auto function

c_NEXT 定义在 class AskBase:

struct Status {
    static auto constexpr   c_ROOT      {-999};
    static auto constexpr   c_PREVIOUS  {-1};
    static auto constexpr   c_NEXT      {1};
    static auto constexpr   c_EOF       {999};
};

后面c_NEXT用于template<typename Container> class AskUI

auto run(){
    auto status = AskBase::Status::c_NEXT;
    for (typename Container::iterator ii=m_asks.begin();
            ii!=m_asks.end();
            ii=(AskBase::Status::c_ROOT==status)? m_asks.begin():
                (AskBase::Status::c_PREVIOUS==status)?(m_asks.begin()==ii?m_asks.begin():ii-1):
                (AskBase::Status::c_NEXT==status)?ii+1:
                m_asks.end())
        status = (*ii)->ask_user();
    return (AskBase::Status::c_NEXT==status);
}

参考三个()?表达式和return语句clang++报告:

error: invalid operands to binary expression ('const std::initializer_list<int>'
and 'std::initializer_list<int>')

解决错误的建议。

使用命令:

clang++ -std=c++1z 

Effective Modern C++ 第 23 页:

in C++11 programming is accidentally declaring a std::initializer_list variable when you mean to declare something else. This pitfall is one of the reasons some developers put braces around their initializers only when they have to.

struct Status {
    static auto constexpr   c_ROOT      =-999;
    static auto constexpr   c_PREVIOUS  =  -1;
    static auto constexpr   c_NEXT      =   1;
    static auto constexpr   c_EOF       = 999;
};

随着 2014 年 11 月委员会会议上的 adoption of N3922,问题中的四个初始化现在将推导出 int 而不是 initializer_list<int>。该论文使 autodirect-list-initialization 上下文中使用(即 auto x{/*...*/};) ill-formed 除非列表仅包含一个元素,在在这种情况下,类型直接从该元素推导出来。 copy-list-initialization - auto x = {/*...*/}; - 保持不变,将推导出 std::initializer_list.

引用该论文中添加到标准中的示例:

auto x3{ 1, 2 }; // error: not a single element
auto x4 = { 3 }; // decltype(x4) is std::initializer_list<int>
auto x5{ 3 }; // decltype(x5) is int

既然论文说了

Direction from EWG is that we consider this a defect in C++14.

并且编译器实现者通常追溯应用缺陷报告,除了 C++1z(17?) 模式外,我们可能会在编译器的 C++11/14 模式中看到它的实现。