次のタイプの特性がある場合、Fields
をいくつかのstd::pair
sで初期化するにはどうすればよいですか?
template <>
struct ManagerDataTrait<Person>
{
static const std::unordered_map<std::string, std::string> Fields;
// ...
};
ラムダを使用してみましたが、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
である可能性がありますが、それは重要ではありません。
Kerrek SBの答えは、一般的に正しい答えです。
const std::unordered_map<std::string, std::string> ManagerDataTrait<Person>::Fields{
{ "blah", "blah" }
// ...
};
(N.B. no template<>
スペシャライゼーションではなく、スペシャライゼーションのメンバーを定義しているため)
ただし、これはVisual C++ではサポートされていないため、もう1つの方法は、関数呼び出しを使用してマップを初期化し、関数から目的のコンテンツを含むマップを返すことです。
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();
ラムダは同じことを行うための単なる構文糖衣です。構文が少し醜いので、ラムダを使用する方が明確かどうかはわかりません。
ブレースリストからマップを初期化できることに気づきましたか?
std::unordered_map<std::string, std::string> m { { "a", "bc" }
, { "b", "xy" }
// ...
};
Visual C++は、ブレースリストからの静的初期化をサポートするようになったため、次のようなことができます。
const std::unordered_map<std::string, std::string> ManagerDataTrait<Person>::Fields{ { "abc", "xyz" }, { "cde", "zyx" } ...};