C ++模板构造函数

时间:2010-10-18 15:50:41

标签: c++ templates constructor

我希望有一个非模板类,其模板构造函数没有参数。

据我所知,它不可能拥有它(因为它会与默认构造函数冲突 - 我是对吗?),,解决方法如下:

class A{
   template <typename U> A(U* dummy) {
   // Do something
   }
};

也许有更好的选择(或更好的解决方法)?

9 个答案:

答案 0 :(得分:91)

调用构造函数模板时无法显式指定模板参数,因此必须通过参数推导推导出它们。这是因为如果你说:

Foo<int> f = Foo<int>();

<int>是类型Foo的模板参数列表,而不是其构造函数。构造函数模板的参数列表无处可去。

即使使用您的解决方法,您仍然必须传递参数才能调用该构造函数模板。一点也不清楚你想要达到的目标。

答案 1 :(得分:32)

您可以创建模板化工厂函数:

class Foo
{
public:
    template <class T> static Foo* create() // could also return by value, or a smart pointer
    {
        return new Foo(...);
    }
...        
};

答案 2 :(得分:23)

  

据我所知,它不可能拥有它(因为它会与默认构造函数冲突 - 我是对的吗?)

你错了。它不会以任何方式发生冲突。你不能永远打电话给它。

答案 3 :(得分:15)

有些观点:

  • 如果您声明任何 构造函数(包括模板化的 一),编译器将克制 声明默认构造函数。
  • 除非你声明一个拷贝构造函数(对于类X一个) 需要XX&X const &)编译器将生成 默认的复制构造函数。
  • 如果为X类提供模板构造函数 T const &TT&然后是。{ 然而,编译器将生成一个 默认非模板化 copy-constructor,即使你认为它不应该,因为当T = X时,声明与copy-constructor声明匹配。
  • 在后一种情况下,您可能希望提供一个非模板化的复制构造函数以及模板化的复制构造函数。他们不会发生冲突。当传递X时,将调用非模板。否则模板化

HTH

答案 4 :(得分:14)

template<class...>struct types{using type=types;};
template<class T>struct tag{using type=T;};
template<class Tag>using type_t=typename Tag::type;

上述帮助程序允许您将类型用作值。

class A {
  template<class T>
  A( tag<T> );
};

tag<T>类型是一个变量,除了它所讽刺的类型之外没有任何状态。您可以使用它将纯类型值传递给模板函数,并使用模板函数推导出类型:

auto a = A(tag<int>{});

您可以传递多种类型:

class A {
  template<class T, class U, class V>
  A( types<T,U,V> );
};
auto a = A(types<int,double,std::string>{});

答案 5 :(得分:2)

你可以这样做:

class C 
{
public:
    template <typename T> C(T*);
};
template <typename T> T* UseType() 
{
    static_cast<T*>(nullptr);
}

然后使用C作为构造函数的模板参数创建类型为int的对象:

C obj(UseType<int>());

由于您无法将模板参数传递给构造函数,因此该解决方案实质上将模板参数转换为常规参数。在调用构造函数时使用UseType<T>()函数使得查看代码的人明白该参数的目的是告诉构造函数使用什么类型。

如果构造函数创建派生类对象并将其分配给作为基类指针的成员变量,则可以使用一个用例。 (构造函数需要知道要使用哪个派生类,但由于始终使用相同的基类指针类型,因此类本身不需要进行模板化。)

答案 6 :(得分:0)

尝试做类似

的事情
template<class T, int i> class A{

    A(){
          A(this)
    }

    A( A<int, 1>* a){
          //do something
    }
    A( A<float, 1>* a){
         //do something
    }
.
.
.
};

答案 7 :(得分:0)

这是一种解决方法。

创建A的模板子类B.在A&#39的构造函数中进行构造独立于模板参数的部分。在B&#39的构造函数中执行依赖于模板参数的部分。

答案 8 :(得分:0)

添加一个虚拟变量很简单

class A {
  template<typename T>
  A(const T&, int arg1, int arg2);
}