tdi*_*ihp 7 c++ templates factory
我想实现一个用于创建对象的工厂函数.我的对象模板如下所示:
template <typename TA, typename TB>
struct MyImpl : public MyInterface
{
// content
};
Run Code Online (Sandbox Code Playgroud)
我的工厂是这样的:
MyInterface* factory(char ta, char tb)
{
if(ta == 'c' && tb == 'c')
{
return new MyImpl<char, char>();
}
if(ta == 'c' && tb == 's')
{
return new MyImpl<char, short>();
}
if(ta == 's' && tb == 'c')
{
return new MyImpl<short, char>();
}
// and so on ....
}
Run Code Online (Sandbox Code Playgroud)
工厂函数必须接受非静态char数据(ta,tb),因为它无法在编译时确定,我认为这是该工厂的重点.事实上,ta并tb从文件(或网络)阅读.
我想要一个更简单的解决方案来避免烦人的2级开关.
我认为我的问题类似于how-would-one-write-a-meta-if-else-if-in-c,除了我不能使用静态参数.
也许我应该回退到C宏并使用一些宏技巧来缩小我当前的代码?
提前致谢!
UPDATE
回答@Rob:
我的实际代码会更复杂,其中包含许多其他内容,更难以阅读,并且在许多方面都没有相关性.我正试图让伪代码正确,如果有任何问题,请通知我:-).
回答@Dynguss:
我的问题是,在我的实际实施,工厂的参数(TA,TB)是在范围较大,如10×ta和20×TB和TA和TB的组合是很长的线,并难以维持.所以我至少需要一些方法来减轻组合的努力.
Ker*_* SB 13
这是一个想法:
template <typename T>
MyInterface * factroy(char t)
{
if (t == 'c') { return MyImpl<T, char>(); }
if (t == 's') { return MyImpl<T, short>(); }
// ...
}
MyInterface * factory(char ta, char tb)
{
if (ta == 'c') { return factroy<char>(tb); }
if (ta == 's') { return factroy<short>(tb); }
// ...
}
Run Code Online (Sandbox Code Playgroud)
使用可变参数模板,此模式可以扩展为任意数量的类型参数 - 例如:
struct Base { virtual ~Base() = default; };
template <typename A, typename B, typename C> struct Foo : Base { };
#include <tuple>
template <typename ...Args>
constexpr Base * factory(std::tuple<Args...>)
{
return new Foo<Args...>;
}
template <typename ...Args, typename ...Char>
constexpr Base * factory(std::tuple<Args...>, char t, Char ... ts)
{
return t == 'c' ? make(std::tuple<char, Args...>(), ts...)
: t == 's' ? make(std::tuple<short int, Args...>(), ts...)
: t == 'i' ? make(std::tuple<int, Args...>(), ts...)
: t == 'l' ? make(std::tuple<long int, Args...>(), ts...)
: nullptr;
}
Run Code Online (Sandbox Code Playgroud)
用法: auto p = factory(std::tuple<>(), 'c', 's', 'l');