error on gcc not clang: cannot convert from '<brace-enclosed initializer list>' to 'std::vector<>

Viewed 387

The following code produces an error only with gcc:

could not convert '{{"John", 32}, {"Theo", 23}, {"Aun", 43}, {"Vivien", 67}}' from '<brace-enclosed initializer list>' to 'std::vector<Person>'
                                 {"Vivien", 67}};
#include <vector>

struct Person{
    //const char* name; // <-- Compiles in both gcc and clang
    char name[32];      // <-- Error in gcc only
    int age;
};

int main(){
    std::vector<Person> parr1 = {{"John", 32},
                                 {"Theo", 23},
                                 {"Aun", 43},
                                 {"Vivien", 67}};
    return 0;
}

(https://godbolt.org/z/1qEaaqcac)

What is the reason for this? Is there a way to get the char array version to compile with gcc?

I'm testing with gcc 8.3 and latest clang.

1 Answers

This is likely due to literal strings being const char* to char[], and therefore without an implicit constructor, the correct aggregate initializer may not be known, and if you want a quick way to compile this with GCC, either do one of the following:

std::vector<Person> parr1 = {
    Person {"John", 32},
    Person {"Theo", 23},
    Person {"Aun", 43},
    Person {"Vivien", 67}
};

This first answer uses explicit aggregate initialization to ensure the type is known at compile time. Another option is:

struct Person{
    const char* name;
    int age;
};

int main(){
    std::vector<Person> parr1 = {
        { "John", 32 },
        { "Theo", 23 },
        { "Aun", 43 },
        { "Vivien", 6 }
    };
    return 0;
}

This simply ensures there is no type conversions required to due aggregate initialization.

Related