C + + 模板构造函数

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

据我所知,这是不可能的(因为它会与缺省构造函数 我说的对吗?发生冲突) ,解决办法如下:

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

也许有更好的替代方案(或者更好的解决办法) ?

194890 次浏览

您可以使用模板化的工厂函数而不是构造函数:

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

据我所知,这是不可能的(因为这会与缺省构造函数冲突——我说的对吗?)

你错了,它没有任何冲突,你只是不能叫它永远。

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

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

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

即使使用了变通方法,您仍然需要传递一个参数来调用构造函数模板。完全不清楚你想达到什么目的。

一些观点:

  • 如果您声明 < strong > any 构造函数(包括模板化的 一) ,编译器将避免 宣布缺省构造函数。
  • 除非您声明了一个复制构造函数(对于类 X1) 它接受 XX&或 < code > X const 编译器将生成 默认复制构造函数。
  • 如果您为类 X 提供了一个模板构造函数,该构造函数采用 T const &TT&然后 编译器仍然会生成一个 默认非模板化 复制构造函数,即使您可能认为它不应该,因为当 T = X 时,声明与复制构造函数声明匹配。
  • 在后一种情况下,您可能希望提供一个非模板化的复制构造函数和模板化的复制构造函数。他们不会冲突。当传递 X 时,将调用非模板化的。否则,模板

高温

试着做一些像

template<class T, int i> class A{


A(){
A(this)
}


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

这里有一个变通方法。

在 A 的构造函数中执行构造中与模板参数无关的部分。在 B 的构造函数中执行与模板参数相关的部分。

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>{});

你可以这样做:

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

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

C obj(UseType<int>());

由于不能将模板参数传递给构造函数,因此此解决方案实际上将模板参数转换为常规参数。在调用构造函数时使用 UseType<T>()函数可以让查看代码的人清楚地知道,该参数的用途是告诉构造函数使用什么类型。

这种情况的一个用例是,如果构造函数创建一个派生类对象,并将其分配给一个成员变量,该变量是一个基类指针。(构造函数需要知道使用哪个派生类,但是类本身不需要进行模板化,因为总是使用相同的基类指针类型。)

只需简单地添加一个虚拟变量,如

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