Uniform initialization with ternary operator return from function

时间:2021-09-13 21:19:48

I don't know if this is a compiler bug (gcc 4.8 on Arch Linux) or a problem with the standard, but the code below fails to compile. Why is getFoo1 allowed but not getFoo2?

我不知道这是一个编译器错误(Arch Linux上的gcc 4.8)还是标准问题,但下面的代码无法编译。为什么允许getFoo1但不允许getFoo2?

struct Foo {
    int _i;
    Foo(int i):_i(i) { }
};

Foo getFoo1(int i) {
    if(i == 3) {
        return { i + 2 };
    } else {
        return { i };
    }
}

Foo getFoo2(int i) {
    return i == 3 ? { i + 2 } : { i };
}

int main() {
    auto foo1 = getFoo1(3); //fine
    auto foo2 = getFoo2(3); //oops
    return 0;
}

1 个解决方案

#1


4  

Braces per se do not form expressions (although all the elements of the initializer list are expressions). A braced-init-list is just a language construct that can be used for initialization in the contexts specified by § 8.5.4 of the C++11 Standard (including return statements).

大括号本身不形成表达式(尽管初始化列表的所有元素都是表达式)。 braced-init-list只是一种语言结构,可用于在C ++ 11标准的第8.5.4节(包括return语句)指定的上下文中进行初始化。

If you want your return statement to compile and still make use of the ternary operator and of list initialization, you have to rewrite it this way:

如果你想让你的return语句编译并仍然使用三元运算符和列表初始化,你必须以这种方式重写它:

return { i == 3 ? i + 2 : i };

Notice, however, that the above is not necessary. As mentioned by David Rodriguez - dribeas in the comments), you could just give up using list initialization. This would work equally well:

但请注意,上述内容不是必需的。正如David Rodriguez所提到的 - 评论中的dribeas,你可以放弃使用列表初始化。这同样有效:

return i == 3 ? i + 2 : i;

#1


4  

Braces per se do not form expressions (although all the elements of the initializer list are expressions). A braced-init-list is just a language construct that can be used for initialization in the contexts specified by § 8.5.4 of the C++11 Standard (including return statements).

大括号本身不形成表达式(尽管初始化列表的所有元素都是表达式)。 braced-init-list只是一种语言结构,可用于在C ++ 11标准的第8.5.4节(包括return语句)指定的上下文中进行初始化。

If you want your return statement to compile and still make use of the ternary operator and of list initialization, you have to rewrite it this way:

如果你想让你的return语句编译并仍然使用三元运算符和列表初始化,你必须以这种方式重写它:

return { i == 3 ? i + 2 : i };

Notice, however, that the above is not necessary. As mentioned by David Rodriguez - dribeas in the comments), you could just give up using list initialization. This would work equally well:

但请注意,上述内容不是必需的。正如David Rodriguez所提到的 - 评论中的dribeas,你可以放弃使用列表初始化。这同样有效:

return i == 3 ? i + 2 : i;