[英]Templated class assignment in C++
This might be a very basic question, but I searched and couldn't find anything. 这可能是一个非常基本的问题,但是我搜索了却找不到任何东西。
I have some code that looks like this: 我有一些看起来像这样的代码:
if(var == 1) {
MyClass<A> x();
x.doThing1();
x.doThing2();
x.doThing3();
...
x.doThing10();
} else if(var == 2) {
MyClass<B> x();
x.doThing1();
x.doThing2();
x.doThing3();
...
x.doThing10();
} else {
MyClass<C> x();
x.doThing1();
x.doThing2();
x.doThing3();
...
x.doThing10();
}
What I'd like to do instead is to cut down the number of lines, eg: 我想做的是减少行数,例如:
// obviously non-working code
MyClass<auto> x;
if(var == 1) {
x<A>();
} else if(var == 2) {
x<B>();
} else {
x<C>();
}
x.doThing1();
x.doThing2();
x.doThing3();
...
x.doThing10();
Is something like this possible? 这样的事情可能吗?
Well, you can just refactor it into something like: 好吧,您可以将其重构为:
template <class T>
void doThings()
{
MyClass<T> t;
t.doThing1();
// ...
t.doThing10();
}
// dispatch
switch (var)
{
case 1: doThings<A>(); break;
case 2: doThings<B>(); break;
// ...
}
There are a few things you can do. 您可以做几件事。
In the general case, if you don't mind dynamic memory allocation, you can take define the interface in a virtual base class, implement the interface in MyClass, using whatever you need from the template parameter. 通常,如果您不介意动态内存分配,则可以使用template参数中的任何内容,在虚拟基类中定义接口,在MyClass中实现接口。 Something along these lines:
遵循以下原则:
#include <memory>
#include <iostream>
class Base
{
public:
virtual void doThing1() const = 0;
virtual void doThing2() const = 0;
virtual void doThing3() const = 0;
};
template <class T>
class MyClass: public Base
{
public:
void doThing1() const {std::cout << T::foo << ".doThing1()" << std::endl;}
void doThing2() const {std::cout << T::foo << ".doThing2()" << std::endl;}
void doThing3() const {std::cout << T::foo << ".doThing3()" << std::endl;}
};
struct A {static const char foo = 'A';};
struct B {static const char foo = 'B';};
struct C {static const char foo = 'C';};
std::unique_ptr<Base> makeMyClassInstance(const int var)
{
switch (var)
{
case 1: return std::make_unique<MyClass<A> >();
case 2: return std::make_unique<MyClass<B> >();
case 3: return std::make_unique<MyClass<C> >();
default: throw std::runtime_error("unsupported");
}
}
int main()
{
int var = 1;
const auto x = makeMyClassInstance(var);
x->doThing1();
x->doThing2();
x->doThing3();
}
If var is not a variable but can be known at compile time, you can have a more radical design. 如果var不是变量,但可以在编译时知道,则可以进行更彻底的设计。 I am skipping the MyClass in this case, but you will get the idea:
在这种情况下,我跳过了MyClass,但是您会明白的:
#include <type_traits>
#include <iostream>
#include <tuple>
struct A{void foo() {std::cout << "A" << std::endl;}};
struct B{void foo() {std::cout << "B" << std::endl;}};
struct C{void foo() {std::cout << "C" << std::endl;}};
template <int I>
struct SelectType
{
typedef typename std::remove_reference<decltype(std::get<I-1> (std::make_tuple(A(), B(), C())))>::type type;
};
template <int I, class T = typename SelectType<I>::type>
T makeMyClassInstance() {return T();}
int main()
{
auto x1 = makeMyClassInstance<2>();
x1.foo();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.