2

Why can't braces initialization operator be used inside of '?' operator?

Am I missing something?

std::function<bool(int,int)> sortfn()
{
    return {};
}

int main(int argc, char *argv[])
{
    bool b = false;
    //auto fn = sortfn();  // compiles OK
    auto fn = b ? sortfn() : {}; // compilation error: syntax error: '{'

    return 0;
}
Alexander Dyagilev
  • 1,139
  • 1
  • 15
  • 43
  • Your reasoning is that the type of `fn` should be determined by the return type of `sortfn` (since it is a tenary expression) and `{}` should work since it does in the function body of `sortfn`, right? Sounds absolutely reasonable to me, good question! – dtell Nov 26 '20 at 11:05
  • 1
    `? :` needs expressions, but `{}` itself is not an expression, it's just a braced list. – Evg Nov 26 '20 at 11:05
  • I found a dupe question. I guess C++14/C++17 standards don't add anything new to the question. – Evg Nov 26 '20 at 11:07
  • I'm not even sure if I understand what the goal is. `auto fn = {}` wouldn't work either. If you do know the type `T` you want to construct, you can write `T{}`. – MSalters Nov 26 '20 at 12:07
  • `auto fn = b ? sortfn() : std::function{};` – Eljay Nov 26 '20 at 14:57
  • @MSalters the "trick" is that the type of a tenary expression is determined by the type of the first expression. So it's very clear that one expects (if you expect this to work at all) the type of `fn` to be the return type of `sortfn()`. – dtell Nov 26 '20 at 15:00
  • 1
    @dtell: The type of the first expression should be `bool` or convert to that. The second and third types are equally important; the rules are symmetric. `a ? b: c` is the same as `(!a) ? c : b`. – MSalters Nov 26 '20 at 15:08
  • 1
    @MSalters sorry, this is a missunderstanding: If you consider `a ? b : c` than the type of `b` determines the type of the expression and hence `c` must also be of the same type (I meant `b` with the first expression). E.g. if you consider `auto fn = false ? 2.f : 1;` the type of `fn` is `float` and its value is `1.f`. It therefore makes sense (if you assume this works at all) to assume that in `auto fn = b ? sortfn() : {};` , `fn` has the type of `sortfn()` and your argument *What should `auto fn = {}` be?* is not valid. The problem in the question is not the type but a missing expression! – dtell Nov 26 '20 at 17:13
  • @dtell: No, the type of `b` does not determine the type of the result. In the `a ? 2.0f : 1` case, there's a _promotion_ of `int` to `float`. For the same reason, in `(!a) ? 1 : 2.0f`, there's also a promotion of `int` to `float`. See `std::common_type`. – MSalters Nov 27 '20 at 07:26

0 Answers0