如何初始化一个静态的std::unordered_map类型特征?

12

给定以下类型特征,我该如何使用一些 std::pair 初始化 Fields

template <>
struct ManagerDataTrait<Person>
{
    static const std::unordered_map<std::string, std::string> Fields;
    // ...
};

我尝试使用lambda,但Visual Studio说Fields不是一个可以显式特化的实体。

template <>
const std::unordered_map<std::string, std::string> ManagerDataTrait<Person>::Fields = []{
    std::unordered_map<std::string, std::string> fields;
    fields.insert(std::make_pair("height", "FLOAT"));
    fields.insert(std::make_pair("mass", "FLOAT"));
    return fields;
};

如果在特质中不能使用静态成员,我有哪些替代方案可以在特质中存储信息呢?(Fields保存了一个SQL数据库结构。)

更新:该成员也可能是const,但这不应该是重点。


你的Lambda需要有实际运行它的东西,但你还没有尝试去做(你只是尝试从Lambda构造哈希映射,这不是有效的,但肯定不能运行Lambda)。 - Jonathan Wakely
3个回答

28

你知道可以使用大括号列表初始化映射吗?

std::unordered_map<std::string, std::string> m { { "a", "bc" }
                                               , { "b", "xy" }
//                                               ...
                                               };

解决方案是去掉template <>,这是你在一个已被删除的评论中指出的。你能把这个加到你的答案里吗?我会标记它为已接受的。 - danijar
我曾经写过(并删除了)这样的评论,你是指那个吗? - Jonathan Wakely
@JonathanWakely 您是正确的,我指的是您的评论。我搞混了。 - danijar

11

Kerrek SB的回答通常来说是正确的:

const std::unordered_map<std::string, std::string> ManagerDataTrait<Person>::Fields{
  { "blah", "blah" }
  // ...
};

(需要注意的是,没有 template<>,因为您正在定义一个特化的成员,而不是一个特化)

但是这在Visual C++中不被支持,因此另一种选择是使用函数调用来初始化map,并从函数返回具有所需内容的map:

std::unordered_map<std::string, std::string>
getFields()
{
  std::unordered_map<std::string, std::string> fields;
  fields["blah"] = "blah";
  // ...
  return fields;
}

const std::unordered_map<std::string, std::string> ManagerDataTrait<Person>::Fields = getFields();
一个lambda只是进行相同操作的语法糖,我不确定使用lambda是否更清晰,因为它的语法有点丑。

2

Visual C++现在支持从花括号列表进行静态初始化,所以您可以像这样做:

const std::unordered_map<std::string, std::string> ManagerDataTrait<Person>::Fields{ { "abc", "xyz" }, { "cde", "zyx" } ...};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接