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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19758343/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:07:47  来源:igfitidea点击:

How to initialize a static std::unordered_map of a type trait?

c++static-memberstemplate-specializationunordered-maptypetraits

提问by danijar

Given the following type trait, how can I initialize Fieldswith some std::pairs?

鉴于以下类型特征,我如何Fields用一些std::pairs 进行初始化?

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

I tried using a lambda but Visual Studio says that Fieldsis not an entity that can be explicitly specialized.

我尝试使用 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;
};

If there is no way to use static members like this in traits, which alternatives do I have to store the information in a trait? (Fieldsholds a SQL database structure.)

如果无法在特征中使用这样的静态成员,那么我必须将信息存储在特征中的哪些替代方法?(Fields包含 SQL 数据库结构。)

Update: The member might be also constbut that shouldn't be the point.

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

采纳答案by Jonathan Wakely

Kerrek SB's answer would be the right answer in general:

Kerrek SB 的答案通常是正确的答案:

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

(N.B. no template<>because you're defining a member of a specialization, not a specialization)

(注意不,template<>因为您正在定义专业化的成员,而不是专业化)

But that isn't supported by Visual C++, so the other alternative is to initialize the map with a function call, and return a map with the desired contents from the function:

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

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();

A lambda is just syntactic sugar for doing the same thing, and I'm not sure it's clearer to use a lambda because the syntax is a bit uglier.

lambda 只是做同样事情的语法糖,我不确定使用 lambda 是否更清晰,因为语法有点难看。

回答by Kerrek SB

You realize you can initialize maps from braced lists?

你意识到你可以从花括号列表初始化地图吗?

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

回答by NiRuKa

Visual C++ now supports static initialization from braced lists, so you could do something like this:

Visual C++ 现在支持从花括号列表进行静态初始化,因此您可以执行以下操作:

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