4

What is wrong with the following C++11 code:

struct S
{
    int a;
    float b;
};

struct T
{
    T(S s) {}
};

int main()
{
    T t(S{1, 0.1});  // ERROR HERE
}

gcc gives an error at the indicated line (I tried both gcc 4.5 and an experimental build of gcc 4.6)

Is this not valid C++11, or is gcc's implementation incomplete?

EDIT: Here are the compiler errors:

test.cpp: In function int main():
test.cpp:14:10: error: expected ) before { token
test.cpp:14:10: error: a function-definition is not allowed here before { token
test.cpp:14:18: error: expected primary-expression before ) token
test.cpp:14:18: error: expected ; before ) token
Raktim Biswas
  • 4,011
  • 5
  • 27
  • 32
HighCommander4
  • 50,428
  • 24
  • 122
  • 194
  • The latter is definitely the case in general - particularly for GCC4.5.x. GCC4.6.x is more complete, but also buggy. Update if you possibly can. – marko Aug 20 '14 at 13:28

2 Answers2

3

According to proposal N2640, your code ought to work; a temporary S object should be created. g++ apparently tries to parse this statement as a declaration (of a function t expecting S), so it looks like a bug to me.

Martin v. Löwis
  • 124,830
  • 17
  • 198
  • 235
0

It seems wrong to call a constructor without parentheses, and this seems to work:

struct S
{
    int a;
    float b;
};

struct T
{
    T(S s) {}
};

int main()
{
    T t(S({1, 0.1}));  // NO ERROR HERE, due to nice constructor parentheses
    T a({1,0.1}); // note that this works, as per link of Martin.
}

It would seem logical (at least to me :s) that your example doesn't work. Replacing S with a vector<int> gives the same result.

vector<int> v{0,1,3}; // works
T t(vector<int>{0,1,2}); // does not, but
T t(vector<int>({0,1,2})); // does
rubenvb
  • 74,642
  • 33
  • 187
  • 332
  • Doesn't that work for the exact same reason that `T a({1,0.1});` works? i.e. isn't `T t(vector({0,1,2}));` just calling the copy constructor of `vector`? – dvide Jan 03 '11 at 10:54
  • Well, two things you can do here: either insert somee parentheses or send a mail to the gcc mailing list to discuss this. The main problem I see is that there are many proposals and addenda for this feature, and I don't know which one GCC wants to implement... – rubenvb Jan 03 '11 at 12:20
  • @dvide right. `T a({1, 0.1})` calls the copy/move constructor of `T`, and initializes the (reference-) parameter of that constructor by a temporary as if initialized by `T tmp = {1, 0.1}`. If you say `S({1, 0.1})` instead of `S{1, 0.1}` you just have added one useless copy/move constructor call instead of directly initializing the object's members. – Johannes Schaub - litb Mar 29 '11 at 15:52