[英]How to create a "factory function" for a templated class?
How would someone go about implementing a factory function for a templated class?有人 go 如何为模板化的 class 实施工厂 function? Either my google searches aren't looking for the right thing, or I am misunderstanding the results.要么我的谷歌搜索没有找到正确的东西,要么我误解了结果。 As an example:举个例子:
template<typename T>
class Test
{
public:
T data;
void SizeOfData() { std::cout << "Data Size:" << sizeof(data) << "\n"; }
};
----this what I am trying to figure out how to do------
template <typename T>
Test<T> FactoryFunction(const std::string& type)
{
if(type == "int")
return Test<int>;
if(type == "long")
return Test<long long>;
}
----------------------------------------
int main()
{
auto a = FactoryFunction(std::string("int"));
auto b = FactoryFunction(std::string("long"));
a.SizeOfData();
b.SizeOfData();
a.data = 1;
b.data = 2;
}
Obviously, this code is all wrong - I am just trying to show what I want to do in theory.显然,这段代码全错了——我只是想在理论上展示我想做的事情。 Can it be done?可以吗? What do I look up in google - Factory functions to return templated classes?我在 google 中查找什么 - 返回模板类的工厂函数? I am not even sure where to start.我什至不知道从哪里开始。 If someone could even point me in a direction - I really just want a function the returns the correct template instantiation based on the results of a switch or if/else list.如果有人甚至可以指出我的方向——我真的只想要一个 function,它会根据开关或 if/else 列表的结果返回正确的模板实例化。 I think conceptually the idea isn't hard, but implementing it is another thing - or I am really missing something.我认为从概念上讲这个想法并不难,但实施它是另一回事 - 或者我真的错过了一些东西。
Thanks for any help.谢谢你的帮助。
The type T of a templated function has to be determined in compile time.模板化 function 的类型 T 必须在编译时确定。 Therefore you cannot do it the way you mentioned.因此,您不能按照您提到的方式进行操作。
However - you can use the following pattern to achieve a similar result:但是 - 您可以使用以下模式来获得类似的结果:
#include <assert.h>
class TestBase
{
public:
virtual void SizeOfData() = 0;
};
template<typename T>
class Test : public TestBase
{
public:
T data;
virtual void SizeOfData() override { std::cout << "Data Size:" << sizeof(data) << "\n"; }
};
std::unique_ptr<TestBase> FactoryFunction(const std::string& type)
{
if (type == "int")
return std::make_unique<Test<int>>();
if (type == "long")
return std::make_unique<Test<long long>>();
return nullptr;
}
int main()
{
auto a = FactoryFunction(std::string("int"));
assert(a);
auto b = FactoryFunction(std::string("long"));
assert(b);
a->SizeOfData();
b->SizeOfData();
return 0;
}
Some notes:一些注意事项:
Each instance of Test (where T changes) is a differnt an unrelated class. In order to create a connection between them, I added a common base class. Test 的每个实例(其中 T 发生变化)都是一个不相关的 class。为了在它们之间创建连接,我添加了一个公共基础 class。
In order to use polymorphism, you must use refernce semantics.为了使用多态性,您必须使用引用语义。 Therefore the factory returns a pointer (in this case a std::unique_ptr
).因此,工厂返回一个指针(在本例中为std::unique_ptr
)。
The common method you need to invoke on all your Test objects ( SizeOfData
) became a virtual method in the base class.您需要在所有测试对象 ( SizeOfData
) 上调用的通用方法成为基类 class 中的虚拟方法。
This technique is actually related to the idiom of type erasure mentioned in the comments.这个技巧其实和评论里提到的type erasure这个习语有关。
UPDATE : based on the comment below, I replaced using naked new
s with std::make_unique
.更新:根据下面的评论,我用std::make_unique
替换了 using naked new
。 You can see more info why it is better here: Differences between std::make_unique and std::unique_ptr with new你可以在这里看到更多信息为什么它更好: Differences between std::make_unique and std::unique_ptr with new
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.