Пользовательский инициализатор скобок

Допустим, у меня есть эта структура:

struct MyStruct {
    int field1;
    char *field2;
    MyStruct(int a, char* b): field2(b) {
        field1 = doStuff(a);
    }
    MyStruct(int a): MyStruct(a, nullptr) {}
    ~MyStruct();
}

Насколько я знаю, это не агрегат, поскольку у меня есть несколько конструкторов.

Чего я хочу добиться, так это использовать инициализатор фигурных скобок по своему усмотрению, что означает использование такого кода:

MyStruct x = { 1, "string" };

который неявно вызывает правильный конструктор (первый в этом случае).

Возможно ли это каким-либо образом?

1 ответ

Решение

Ты почти там. MyStruct x = { 1, "string" }; называется инициализация списка копирования. Он попытается построить MyStruct из доступных конструкторов с параметрами, предоставленными из списка braced-init-list

Ваша проблема в том, что ваш конструктор принимает char* в то время как "string" это const char[N] который может распасться на const char*не char*, Таким образом, делая вещи, которые меняются

struct MyStruct {
    int field1;
   const char* field2;
    MyStruct(int a, const char* b): field2(b) {
        field1 = a;
    }
    MyStruct(int a): MyStruct(a, nullptr) {}
    ~MyStruct() {}
};

затем

MyStruct x = { 1, "string" };

Буду работать. Если вы хотите сделать это немного более пуленепробиваемым, вы можете изменить field2 быть std::string и использовать

struct MyStruct {
    int field1;
    std::string field2;
    MyStruct(int a, const std::string& b): field1(a), field2(b) {}
    MyStruct(int a): MyStruct(a, "") {}
    ~MyStruct() {}
};
Другие вопросы по тегам