ステップ1:ここでは
template <typename T>
void MyClass::func(T)
{
myMap.find(std::type_index(typeid(T)));
}
はサポートの欠如のデモではstd用に独自
boost::serialization::load/save<>
のオーバーロードを定義します:: type_index
ステップ2:文字列をtype_indexにマッピングする手段を提供します。
手順3:type_indexをアーカイブの名前で格納します。
もちろん、地図にキーとして使用するすべてのタイプの名前を登録することを忘れないでください。下の例では、register_name("Foo", typeid(Foo));
などを呼び出してこれを行います。
#include <iostream>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/split_free.hpp>
#include <fstream>
#include <sstream>
#include <typeindex>
#include <tuple>
#include <vector>
#include <string>
struct nothing {};
using named_typeindex = std::tuple<std::string, std::type_index>;
std::vector<named_typeindex> name_register =
{
};
std::type_index type_for_name(const std::string& name)
{
auto i = std::find_if(std::begin(name_register), std::end(name_register),
[&name](const auto& entry) { return std::get<std::string>(entry) == name; });
if (i == std::end(name_register))
return typeid(nothing);
return std::get<std::type_index>(*i);
}
std::string const& name_for_type(std::type_index type)
{
auto i = std::find_if(std::begin(name_register), std::end(name_register),
[type](const auto& entry) { return std::get<std::type_index>(entry) == type; });
using namespace std::string_literals;
if (i == std::end(name_register))
throw std::logic_error("unregistered type "s + type.name());
return std::get<std::string>(*i);
}
bool register_name(std::string name, std::type_index ti)
{
if (type_for_name(name) == typeid(nothing))
{
name_register.push_back(std::make_tuple(std::move(name), ti));
return true;
}
return false;
}
namespace boost {
namespace serialization {
template<class Archive>
void save(Archive & ar, const std::type_index & t, unsigned int version)
{
ar << name_for_type(t);
}
template<class Archive>
void load(Archive & ar, std::type_index & t, unsigned int version)
{
std::string s;
ar >> s;
t = type_for_name(s);
}
} // namespace serialization
} // namespace boost
BOOST_SERIALIZATION_SPLIT_FREE(std::type_index);
int main()
{
std::type_index myTypeIndex = typeid(double);
std::ostringstream outputStream {};
boost::archive::text_oarchive outputArchive(outputStream);
outputArchive << myTypeIndex;
std::cout << outputStream.str() << std::endl;
return 0;
}
危険です。先の地雷畑。コンパイラによって構築されたものではなく、構築できるものにインデックスを付けたいと思うでしょう。残念ながら、typeidの周りに独自の多型、直列化可能なラッパーを作成する必要があります。 –
@RichardHodges 'std :: unordered_mapを使うのは、一般的には悪い考えですか?それとも、シリアル化する必要があるときだけですか? –
いいえ、type_indexはインデックスとして使用するように設計されています。あなたが構築を制御していないので、単にboost :: serializeと互換性がありません。少なくとも、カスタムのロード/ストア関数を提供する必要があります。 –