2016-04-19 8 views
2

У меня есть класс Сорт, как:(VS2015) Попытка заполнить статическую карту с данными из списка инициализаторов

class Object { 
public: 
    struct Flag { 
     const uint32_t bit = 0; 
     const wchar_t* name = L""; 
     const wchar_t sign = L""; 
    } 

    static std::map<const char*, Flag> Flags; 
} 

Я в настоящее время на VS2015, но хочу поддержать лязг и GCC (последний). Моя проблема в том, что я не могу понять, как на самом деле инициализировать эту карту данными.

Я попытался положить его рядный, как:

static std::map<const char*, Flag> Flags = { 
    { "FOO1",  { 0, L"FOO1",  L'A' } }, 
    { "FOO2",  { 1, L"FOO3",  L'B' } }, 
    { "FOO3",  { 2, L"FOO3",  L'C' } } 
} 

Но жаловалась, что только константные интегральные типы могут быть в классе. Хорошо! Так что я просто оставил его в качестве декларации в определении класса (как показано в первом фрагменте кода), и поместить его в соответствующем CPP:

static std::map<const char*, Object::Flag> Object::Flags = { 
    { "FOO1",  { 0, L"FOO1",  L'A' } }, 
    { "FOO2",  { 1, L"FOO3",  L'B' } }, 
    { "FOO3",  { 2, L"FOO3",  L'C' } } 
} 

Теперь это жалуется, что:

error C2440: 'initializing': cannot convert from 'initializer list' to 'std::map,std::allocator>>'

вещь, я мог бы присяжный У меня было это работает, поэтому я думаю, что я должен иметь синтаксис неправильно. Если нет, ясно, что мне не хватает загрузки статической карты в пространство имен классов.

ответ

3

Согласно стандарту C++ 11, Flag не является совокупностью из-за e наличие инициализаторов с привязкой или равными (как инициализаторы элементов по умолчанию), поэтому попытка использовать инициализацию агрегата для инициализации не выполняется. C++ 14 removed this restriction, поэтому Flag считается агрегатом в соответствии с этой версией стандарта и your code is valid.

Вот еще более простая версия вашего примера, которая не скомпилирована с -std=c++11, но успешно компилируется с -std=c++14.

#include <stdint.h> 

struct Flag { 
    const uint32_t bit = 0; 
    const wchar_t* name = L""; 
    const wchar_t sign = L' '; 
}; 

int main() 
{ 
    Flag f{ 0U, L"FOO1", L'A' }; 
} 

Live demo.

VS2015 по-прежнему имеет поведение C++ 11, поэтому ваши параметры должны либо удалить инициализаторы элемента по умолчанию (таким образом, сделать агрегат), либо предоставить конструктор для Object::Flag.

6

Вы не можете инициализировать объект Object::Flag, используя синтаксис инициализации списка, { 0, L"FOO1", L'A' }, поскольку он имеет инициализаторы элементов по умолчанию. См. http://en.cppreference.com/w/cpp/language/list_initialization для более подробной информации.

Вы не можете использовать агрегатную инициализацию формы

Object::Flag f = { 0, L"FOO1", L'A'}; 

по той же причине. См. http://en.cppreference.com/w/cpp/language/aggregate_initialization.

Изменение Object::Flag к более простой форме:

struct Flag { 
    const uint32_t bit; 
    const wchar_t* name; 
    const wchar_t sign; 
}; 

, а затем вы должны быть в состоянии использовать:

std::map<const char*, Object::Flag> Object::Flags = { 
    { "FOO1", { 0, L"FOO1", L'A' } }, 
    { "FOO2", { 1, L"FOO3", L'B' } }, 
    { "FOO3", { 2, L"FOO3", L'C' } }}; 

После этого, вы должны быть в состоянии использовать:

Object::Flag f = { 0, L"FOO1", L'A'}; 
+0

Это неправда больше с C++ 14 Я думаю (похоже, VS немного опоздал). – Holt

+0

@ Хольт, это приятно знать. Спасибо за головы. –

+0

Эта ссылка может дополнять ваши. Я думаю: http://en.cppreference.com/w/cpp/language/aggregate_initialization – Holt

 Смежные вопросы

  • Нет связанных вопросов^_^