2

Here is my code:

struct MyTest{
    int a;
    char b;
};
void testFunc(MyTest mt){
    cout << mt.a << mt.b << endl;
}
void main(){
    testFunc({ 1, 'c' });
}

It seems that mt will get constructed from the initializer_list and testFunc will output the right result. But how can it be since I didn't implement a constructor accepting an initializer_list at all.

0

4 Answers 4

7

This class is an aggregate - a simple structure containing public data members and no user-defined constructors and the like.

List-initialisation is supported for aggregate types; the elements of the initialiser list are used to initialise each data member in turn. This has been supported for variable initialisation in both C and C++ for a very long time:

MyTest x = {1, 'c'};

and C++11 extended this to other uses of list-initialisation, including (in this case) initialising a temporary function argument.

Sign up to request clarification or add additional context in comments.

Comments

3

list-initialization is occurring. Since (as in C) you can initialize the type with

MyTest mt = {1, 'c'};

the same initialization takes place at the point of the call

(N3690) 8.5/17 [...]

-- If the initializer is a (non-parenthesized) braced-init-list, the object or reference is list-initialized

8.5.4/3 gives the example:

struct S2 { // OK
  int m1; 
  double m2, m3; 
}; 
S2 s21 = { 1, 2, 3.0 };  // OK

Calling the function with an initializer list behaves the same way. Further:

(8.5.1/1) An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3). When an aggregate is initialized by an initializer list, as specified in 8.5.4, the elements of the initializer list are taken as initializers for the members of the aggregate, in increasing subscript or member order.

Comments

0

In C++11 we don't have to define a constructor for a POD. We can use the new list-initialization syntax:

MyTest mt{1, 'c'};
MyTest mt2 = {1, 'c'};

this is what's being called in your code.

Comments

-5

Well, first of you main function is wrong:

int main() {
/* ... code ... here */
return 0;
}

Second, you need a object to initialize your struct:

#include <iostream>

struct Foo {
    char _a;
    int _b;
};

void print_them (const Foo& foo) {
    std::cout << foo._a << ", " << foo._b << std::endl;
}

int main () {
    /* create object and initialize it */
    Foo f = {
        'a', 7
    };
    /* call function */
    print_them (f);
    return 0;
}

2 Comments

fyi, main will implicitly return 0; if it reaches the end. You may omit the return. this is only true for main
no he doesn't need a separate object to initialize his struct. His code is fine. And this doesn't answer the question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.