Существует ли способ инициализации новой переменной структуры, не требующий написания конструктора?


Я думаю, что смутно припоминаю, что один из новых стандартов c++ (может быть, его c++11, а может быть, 14?...17??) позволяет инициализировать структуру, в результате чего вы можете определить структуру и затем инициализировать ее без необходимости писать конструктор.

Например:

struct test
{
    int a;
    int b;
    std::string str;
};

int main()
{
    std::map<int, test> test_map;
    test_map[0] = test(1, 2, "test1"); // This is the line in question
    // Or it might be more like: test_map[0] = test{1, 2, "test1"};
    return 0;
}
Я не могу вспомнить название этой специальной инициализации (или если она вообще существует)!. Итак, мои вопросы таковы:
  • есть ли какой-то новый механизм для достижения этого без написания конструктора в структуре "тест"?
  • Если да, то как он называется (чтобы я мог прочитать о нем подробнее).

Если эта "особенность" не существует, то, пожалуйста, избавьте меня от моих страданий!- может быть, мое воображение все это выдумало...

3 6

3 ответа:

"инициализация без конструктора" называетсяагрегатной инициализацией , она всегда была частью C++ с первого дня. К сожалению, некоторые могут сказать.

В C++98 можно написать:

std::map<int, test> test_map;
test temp = { 1, 2, "test1" };
test_map[0] = temp;

C++11 добавил, что вы можете использовать агрегатную инициализацию в prvalues, поэтому вам не нужно объявлять промежуточную переменную (и нет никаких дополнительных копий):

std::map<int, test> test_map;
test_map[0] = { 1, 2, "test1" };

std::map<int, test> m2 = { {0, {1, 2, "test2"}} };    // and this

Без конструктора, вы можете сделать это так

test_map[0] = test{ 1, 2, "test1" };

Или просто

test_map[0] = { 1, 2, "test1" };

Можно также инициализировать по умолчанию:

struct test {
    int a{1};
    int b{2};
    std::string str{"test1"};
};

Или построить без присвоения:

std::map<int, test> test_map{ 
    {0, {1, 2, "test1"}}
};

Или вставить без копии:

test_map.emplace(std::piecewise_construct,
    std::forward_as_tuple(0),
    std::forward_as_tuple(1, 2, "test1"));