Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

initializer_list and default constructor overload resolution

Tags:

c++

c++11

#include <initializer_list>
#include <iostream>
using namespace std;

struct Y {};

struct X
{
    X(initializer_list<Y>) { cout << "yay" << endl; }
    explicit X() { cout << "boo" << endl; }
};

X f()
{
    return {};
}

int main()
{
    f();

    return 0;
}

This prints out "boo". Why doesn't it print out "yay" ?

Is there anyway to differentiate the following two constructions:

  1. X()
  2. X{}

or

  1. return X();
  2. return {};

or

void g(const X&)
  1. g(X())
  2. g({})

Thanks.

like image 712
Andrew Tomazos Avatar asked Dec 22 '22 03:12

Andrew Tomazos


2 Answers

Is there anyway to differentiate the following two constructions:

No. They are not different constructs.

The primary purpose of the {} constructor syntax was to introduce uniform initialization, to have initialization work the same everywhere. If there was a difference between them, it wouldn't be uniform.

If you want to use the empty initializer list constructor, you have to state that you're passing an initializer list explicitly. Like this: return initializer_list<Y>{}; Of course, one of the other purposes of uniform initialization is to not have to type out typenames so much, so you can achieve the same effect with return {{}};

like image 105
Nicol Bolas Avatar answered Dec 24 '22 01:12

Nicol Bolas


return {}; will always use a default constructor if there is one.

return X({}); or return {{}}; will construct from an empty initialiser list.

like image 28
Mike Seymour Avatar answered Dec 24 '22 01:12

Mike Seymour