C ++ 11 пытается понять, почему я не могу унифицировать init структуру, но я могу инициализировать std :: pair аналогичного типа - PullRequest
0 голосов
/ 27 марта 2019

С учетом следующего кода:

#include <functional>
#include <string>
#include <iostream>

class test
{
public:
    struct info
    {
        std::string name {""};
        std::function<bool()> func;
    };

    //info my_info { "test_name", [&]{return member_func();} }; // <------ ERROR HERE

    std::pair<std::string, std::function<bool()>> my_info_pair { "test_name", [&]{return member_func();} };

    bool member_func()
    {
        std::cout << "member_func\n";
        return true;
    };

};

int main() {
    std::cout << "start\n";
    test t;
    std::cout << t.my_info_pair.first << std::endl;
    t.my_info_pair.second();
    std::cout << "end\n";
}

Этот код работает.Но если я раскомментирую закомментированную строку, которая пытается инициализировать структуру info так же, как инициализирует std :: pair, то это не удастся.Я не могу понять, почему ...

Ошибка:

prog.cc:15:60: error: could not convert '{"test_name", <lambda closure
object>test::<lambda()>{((test*)this)}}' from '<brace-enclosed
initializer list>' to 'test::info'
     info my_info { "test_name", [&]{return member_func();} };
                                                             ^

Ссылка на мой тестовый код: здесь (wandbox)

1 Ответ

5 голосов
/ 27 марта 2019

Проблема здесь

std::string name {""};

. Вы используете инициализатор члена класса и в C ++ 11, что недопустимо, если вы хотите, чтобы объект был агрегатным (для [dcl.init.aggr] / 1 ).Чтобы компилировать это в C ++ 11, вы должны удалить его.

В C ++ 14 и выше это ограничение было удалено (обновлено [dcl.init.aggr] / 1 ) и в членах класса инициализаторы разрешены в агрегатах, и код будет компилироваться как есть.

...