Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Uniform initialization with ternary operator return from function

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?

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;
}
like image 941
Átila Neves Avatar asked Feb 04 '26 08:02

Átila Neves


1 Answers

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).

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 { 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:

return i == 3 ? i + 2 : i;
like image 80
Andy Prowl Avatar answered Feb 06 '26 23:02

Andy Prowl



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!