(VS2015) 尝试用初始化列表中的数据填充静态映射
(VS2015) Attempting to fill a static map with data from initializer list
我有一个 class 有点像:
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,但希望支持 clang 和 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' } }
}
但是那抱怨说只有 const 整数类型可以是 in-class。好的!所以我只是将它保留为 class 定义中的声明(如第一个代码片段所示),并将其放入关联的 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>>'
问题是,我本可以发誓我已经成功了,所以我想我一定是语法错误。如果没有,显然我不知道如何将静态映射加载到 classes 命名空间。
您不能使用列表初始化语法 { 0, L"FOO1", L'A' }
来初始化 Object::Flag
的对象,因为它具有默认的成员初始值设定项。有关详细信息,请参阅 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'};
根据 C++11 标准,Flag
不是聚合,因为存在大括号或相等初始化器(也称为默认成员初始化器),因此尝试使用聚合初始化来初始化失败。 C++14 removed this restriction, so Flag
is considered an aggregate according to that version of the standard, and 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' };
}
VS2015 仍然具有 C++11 行为,因此您的选择是删除默认成员初始值设定项(从而使 Flag
成为聚合),或为 Object::Flag
提供构造函数。
我有一个 class 有点像:
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,但希望支持 clang 和 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' } }
}
但是那抱怨说只有 const 整数类型可以是 in-class。好的!所以我只是将它保留为 class 定义中的声明(如第一个代码片段所示),并将其放入关联的 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>>'
问题是,我本可以发誓我已经成功了,所以我想我一定是语法错误。如果没有,显然我不知道如何将静态映射加载到 classes 命名空间。
您不能使用列表初始化语法 { 0, L"FOO1", L'A' }
来初始化 Object::Flag
的对象,因为它具有默认的成员初始值设定项。有关详细信息,请参阅 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'};
根据 C++11 标准,Flag
不是聚合,因为存在大括号或相等初始化器(也称为默认成员初始化器),因此尝试使用聚合初始化来初始化失败。 C++14 removed this restriction, so Flag
is considered an aggregate according to that version of the standard, and 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' };
}
VS2015 仍然具有 C++11 行为,因此您的选择是删除默认成员初始值设定项(从而使 Flag
成为聚合),或为 Object::Flag
提供构造函数。