具有非参数模板类型的类构造函数

时间:2009-09-19 02:36:11

标签: c++ templates

对于普通的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的实例时,我找不到向构造函数提供参数的方法。

有没有办法做到这一点没有将类转换为模板化类或将一些未使用的T对象发送给构造函数?

3 个答案:

答案 0 :(得分: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>()));

答案 1 :(得分:3)

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

您可以合理地希望,如果内联构造函数,则实际上永远不会创建类型标记。

答案 2 :(得分:0)

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

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

你会写

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

显然不如(1)那么漂亮,但恕我直言比使用类型标签更清晰。 (编译器将在实践中删除副本。)

BTW是否有理由不能简单地将factory作为课程模板?然后(1)的语法将编译。 (但这意味着不能将不同类型的工厂分配给彼此。)