I have a xml where I read from the types of the object that needs to be created,the problem lies to how I can pass the enum without having to use a switch/if statement.
我有一个xml,我从需要创建的对象的类型中读取,问题在于如何在不使用switch / if语句的情况下传递枚举。
enum ObjectType {A,B,C};
void parseXML(const string& fileName)
{
//Open-read file etc...
ObjectType objType = xmlObject.type(); <- the structure provided from the xml parser that I use(codesynthesis)
ObjectParameters params = gatherParameters(xmlObject);
auto createdObj = factory.createObject<objType>(params);
^^^^^
}
A constant expression is required,so do I have to map the provided types or is there any faster way? And if so is there a way to use the enum as a tag/synonym for the classes?
需要一个常量表达式,所以我必须映射提供的类型还是有更快的方法?如果是这样,有一种方法可以使用枚举作为类的标记/同义词吗?
1 个解决方案
#1
3
auto magic_switch=[]( auto value, auto limit ){ // limit must be compile time type value
return [value,limit](auto&&f){
auto* pf=std::addressof(f);
using ptr=decltype(pf);
auto index=indexer<limit>();
using R=decltype((decltype(f)(*pf))(limit));
using Sig=R(*)(ptr pf);
static const auto table=index(
[](auto...Is)
->std::array<Sig, decltype(limit){}>
{
return {{
+[](ptr pf)->R
{
return (decltype(f)(*pf))( decltype(Is){} );
}...
}};
}
);
return table[value](pf);
};
};
Where indexer is
索引器在哪里
template<std::size_t I>using index_t=std::integral_constant<std::size_t, I>;
template<std::size_t I>constexpr index_t<I> index_k{};
template<class=void, std::size_t...Is>
auto indexer(std::index_sequence<Is...>){
return [](auto&&f){
return f( index_k<Is>... );
};
}
template<std::size_t N>
auto indexer(){
return indexer(std::make_index_sequence<N>{});
}
Then your code;
那你的代码;
auto createdObj = factory.createObject<objType>(params);
// work with it
Becomes:
变为:
magic_switch( objType, index_k<3> )
([&](auto index){
auto createdObj = factory.createObject<(ObjectType)index>(params);
// work with it
});
实例。
Note you end up in subscope within a lambda; there is no way to avoid that.
注意你最终在lambda中的子视图中;没有办法避免这种情况。
#1
3
auto magic_switch=[]( auto value, auto limit ){ // limit must be compile time type value
return [value,limit](auto&&f){
auto* pf=std::addressof(f);
using ptr=decltype(pf);
auto index=indexer<limit>();
using R=decltype((decltype(f)(*pf))(limit));
using Sig=R(*)(ptr pf);
static const auto table=index(
[](auto...Is)
->std::array<Sig, decltype(limit){}>
{
return {{
+[](ptr pf)->R
{
return (decltype(f)(*pf))( decltype(Is){} );
}...
}};
}
);
return table[value](pf);
};
};
Where indexer is
索引器在哪里
template<std::size_t I>using index_t=std::integral_constant<std::size_t, I>;
template<std::size_t I>constexpr index_t<I> index_k{};
template<class=void, std::size_t...Is>
auto indexer(std::index_sequence<Is...>){
return [](auto&&f){
return f( index_k<Is>... );
};
}
template<std::size_t N>
auto indexer(){
return indexer(std::make_index_sequence<N>{});
}
Then your code;
那你的代码;
auto createdObj = factory.createObject<objType>(params);
// work with it
Becomes:
变为:
magic_switch( objType, index_k<3> )
([&](auto index){
auto createdObj = factory.createObject<(ObjectType)index>(params);
// work with it
});
实例。
Note you end up in subscope within a lambda; there is no way to avoid that.
注意你最终在lambda中的子视图中;没有办法避免这种情况。