ジェネリック型のパラメーターのリスト(ParameterList)を保持するためのクラスがあります。多くのクラスは通常、コンストラクターでParameterListを受け入れますが、いくつかのクラスは少数のパラメーターのみを必要とするため、簡略化されたバージョンも提供したいと思います。
問題はこの2番目のバージョンにあります。典型的な使用法を示す例を書きました。
#include <string>
#include <map>
#include <memory>
#include <vector>
#include <iostream>
struct Parameter
{
};
template<typename T>
struct TypedParameter : public Parameter
{
TypedParameter (const T& data): data(data){};
T data;
};
struct ParameterList
{
std::map<std::wstring, std::shared_ptr<Parameter>> list;
template<class T> void addParameter(const std::wstring& name, const T& param)
{
list[name] = std::shared_ptr<Parameter>(new TypedParameter<T>(param));
}
template<class T> T& getParameter(const std::wstring& name) const
{
return static_cast<TypedParameter<T>*>(list.at(name).get())->data;
}
};
class Test
{
private:
/*const*/ ParameterList _param;
protected:
public:
Test(ParameterList p):
_param(p)
{
}
Test(const std::wstring& name, int age)
{
_param.addParameter<std::wstring>(L"name", name);
_param.addParameter<int>(L"age", age);
}
void Present()
{
std::wcout << L"My name is " << _param.getParameter<std::wstring>(L"name");
std::wcout << L" and I'm " << _param.getParameter<int>(L"age") << L" years old." << std::endl;
}
};
int main()
{
ParameterList l;
l.addParameter<int>(L"age", 16521);
l.addParameter<std::wstring>(L"name", L"Bahamut");
std::wcout << L"name: " << l.getParameter<std::wstring>(L"name") << std::endl;
std::wcout << L"age: " << l.getParameter<int>(L"age") << std::endl;
Test t1(l);
Test t2(L"Tiamat", 15525);
t1.Present();
t2.Present();
getchar();
}
t2は機能しますが、主に2つの問題があります。最初に新しいコンストラクターを作成する必要があり、次に「_param」をconstにすることをあきらめる必要があります。
次のような新しいコンストラクターをParameterListに追加することを考えていました。
template<typename... Values>
ParameterList(std::initializer_list<std::wstring> keys, const Values&... values)
{
//?
}
//Later
Test t3({L"name", L"age"}, L"Vorel", 19870);
しかし、どうすれば値を正しく解凍できますか?