2009-09-19 182 views
2

对于一个普通的C++函数,它可能在参数列表不显示模板参数:类的构造函数与非参数模板类型

template<typename T> 
T default_construct() 
{ 
    return T(); 
} 

some_type x = default_construct<some_type>(); 

即使调用此我使用的类型不在参数列表中,我仍然可以将它传递给函数。现在,我想这样做在类的构造函数:

struct Base; 

template<typename T> 
Base* allocate() 
{ 
    return new T; //Assume T derives from Base... 
} 

struct factory { 
    template<typename T> 
    factory() 
     : func(allocate<T>) 
    {} 

    std::tr1::function<Base*()> func; 
}; 

,但我不能找到一种方法,参数向构造函数时,我想构建的factory一个实例。

有没有办法做到这一点没有把类变成模板类或发送一些未使用的对象到构造函数?

回答

9

不,没有办法做到这一点。在14.8.1/5在标准的说明解释了为什么

[注:由于显式模板参数列表如下函数模板名称,因为转换成员函数模板和构造成员函数模板被称为不使用功能名称,还有没有办法为这些函数模板提供显式的模板参数列表。 ]

当然,它不需要是您发送的T对象。它可以是已经T编码,其类型

template<typename T> struct type2type { }; 

struct factory { 
    template<typename T> 
    factory(type2type<T>) 
     : func(allocate<T>) 
    {} 

    std::tr1::function<Base*()> func; 
}; 

factory f((type2type<Foo>())); 
+0

好吧,标准答案很引人注目。谢谢。 – CAdaker 2009-09-19 02:48:43

3

没有任何对象,你不能。使用“类型标签对象”来调用给定类型的未使用对象。您可以创建每种类型的全局变量,也可以每次使用默认的构造函数。

你可以合理地希望,如果构造函数是内联的,那么类型标签永远不会被创建。

0

litb's和wrang-wrang的答案很好。作为一种可能性,您可以考虑将所有(非复制)构造函数声明为私有或受保护的,并创建一个或多个静态成员函数模板factory create<T>()。然后,定义一个工厂实例,而不是

factory<SomeType> f;      // 1 (doesn't compile) 

你会写

factory f(factory::create<SomeType>()); // 2 

显然不是一样漂亮(1),但恕我直言不是使用类型标签稍微清晰。 (编译器将在实践中消除副本。)

顺便说一句,有没有原因,你不能简单地使factory类模板?然后从(1)的语法将被编译。 (但这意味着不同类型的工厂不能被分配到另一个工厂)。