我希望有一个没有参数的模板构造函数的非模板类。
据我了解,不可能拥有它(因为它会与默认构造函数冲突-对吗?),解决方法如下:
class A{
template <typename U> A(U* dummy) {
// Do something
}
};
也许有更好的选择(或更好的解决方法)?
调用构造函数模板时无法显式指定模板参数,因此必须通过参数推导来推导。这是因为如果你说:
Foo<int> f = Foo<int>();
<int>
是类型 Foo
的模板参数列表,而不是它的构造函数。构造函数模板的参数列表无处可去。
即使使用您的解决方法,您仍然必须传递一个参数才能调用该构造函数模板。完全不清楚您要达到的目标。
您可以使用模板化工厂函数而不是构造函数:
class Foo
{
public:
template <class T> static Foo* create() // could also return by value, or a smart pointer
{
return new Foo(...);
}
...
};
return Foo(...);
感谢@Samuel_xL。这对我来说是个好主意。
据我了解,不可能拥有它(因为它会与默认构造函数冲突 - 我是对的吗?)
你错了。它不会以任何方式发生冲突。你永远不能调用它。
int *p; A a(p)
。 2. 偏见或理想化 ;-) 没有 John Doe。没有什么典型的德国人……用约翰内斯的话来说绝对不是。如果它们听起来没有幽默感,那只是因为 C++ 没有幽默感。
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>{});
几点:
如果您声明任何构造函数(包括模板化构造函数),编译器将避免声明默认构造函数。
除非您声明一个复制构造函数(对于采用 X 或 X& 或 X const & 的 X 类),否则编译器将生成默认的复制构造函数。
如果您为接受 T const & 或 T 或 T& 的类 X 提供模板构造函数,那么编译器仍然会生成一个默认的非模板化复制构造函数,即使您可能认为它不应该,因为当 T = X 声明匹配复制构造函数声明。
在后一种情况下,您可能希望提供一个非模板复制构造函数以及模板复制构造函数。他们不会冲突。当 X 被传递时,非模板将被调用。否则模板化
高温高压
struct S { template<typename T> S() { } };
的类声明了一个“无法访问的 ctor”。没有办法推断或通过 T
。尽管如此,由于似乎存在用户定义的 ctor,因此不会生成默认 ctor。
你可以这样做:
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>()
函数可以让查看代码的人清楚地知道,该参数的目的是告诉构造函数使用什么类型。
一个用例是构造函数创建派生类对象并将其分配给作为基类指针的成员变量。 (构造函数需要知道要使用哪个派生类,但类本身不需要模板化,因为始终使用相同的基类指针类型。)
这是一种解决方法。
创建 A 的模板子类 B。在 A 的构造函数中执行与模板参数无关的构造部分。在 B 的构造函数中执行与模板参数相关的部分。
尝试做类似的事情
template<class T, int i> class A{
A(){
A(this)
}
A( A<int, 1>* a){
//do something
}
A( A<float, 1>* a){
//do something
}
.
.
.
};
只需简单地添加一个虚拟变量,例如
class A {
template<typename T>
A(const T&, int arg1, int arg2);
}