我经常发现需要使用以下模式:
template<typename T>
class SomeClass : public Base {
SomeClass(const T& t) {...}
...
};
template<typename T>
SomeClass<T>* makeSomeClass(const T& t) {
return new SomeClass<T>(t);
}并使用它:
Base* = makeSomeClass(123);当我不想显式地指定T时,这是很有用的,因为它是一个非常复杂的(函数类型等),并且函数参数可以隐式推导出类型。
有没有办法在没有额外的"make“函数的情况下做到这一点?为什么模板推导只适用于函数参数,而不适用于构造函数参数?
发布于 2011-06-27 02:20:47
不,没有额外的make函数是无法做到这一点的。
它不能与构造函数一起工作的原因是因为它太复杂了。请考虑以下内容:
template <typename T>
struct Foo
{
Foo(const T& val) { ... }
Foo(const Foo<T>& other) { ... } // Copy constructor
};
Foo<int> x;如果我调用:
Foo(x);这给了我一个Foo< Foo<int> >,还是我调用了一个Foo<int>的复制构造函数
它在太多的地方会有歧义,所以额外的函数是必要的。
请注意,您可以通过使用模板模板来自动创建make函数:
template <template <typename> class TemplateClass, typename Type>
TemplateClass<Type> make(const Type& x)
{
return TemplateClass<Type>(x);
}然后,您可以使用:
make<SomeClass>(123); // returns a SomeClass<int>发布于 2011-06-27 02:16:28
如果构造函数本身是一个模板,那么它可以在构造函数参数中工作。不同之处在于,当您使用帮助器时,您使用的是函数模板,其中编译器可以推断类型。如果没有帮助器,您将使用类模板,在调用(非模板)构造函数之前,编译器必须以某种方式推断类型。
发布于 2011-06-27 02:15:46
有没有一种不需要额外功能的方法?不,没有。为什么只对函数有效?因为对于函数,您实际上提供了参数。如果它被允许用于类,那么推断模板参数的唯一方法将是在调用构造函数进行初始化的情况下,这会产生许多额外的规则和异常,并使事情变得复杂。
https://stackoverflow.com/questions/6485791
复制相似问题