C++ 模板构造函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3960849/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++ template constructor
提问by Yippie-Ki-Yay
I wish to have a non-template class with a template constructor with no arguments.
我希望有一个带有不带参数的模板构造函数的非模板类。
As far as I understand, it's impossible to have it (because it would conflict with the default constructor - am I right?), and the workaround is the following:
据我了解,不可能拥有它(因为它会与默认构造函数冲突 -我对吗?),解决方法如下:
class A{
template <typename U> A(U* dummy) {
// Do something
}
};
Maybe there is a better alternative for this (or a better workaround)?
也许有更好的选择(或更好的解决方法)?
采纳答案by James McNellis
There is no way to explicitly specify the template arguments when calling a constructor template, so they have to be deduced through argument deduction. This is because if you say:
调用构造函数模板时无法显式指定模板参数,因此必须通过参数推导来推导它们。这是因为如果你说:
Foo<int> f = Foo<int>();
The <int>
is the template argument list for the type Foo
, not for its constructor. There's nowhere for the constructor template's argument list to go.
的<int>
是该类型的模板参数列表Foo
,而不是它的构造函数。构造函数模板的参数列表无处可去。
Even with your workaround you still have to pass an argument in order to call that constructor template. It's not at all clear what you are trying to achieve.
即使使用您的解决方法,您仍然必须传递参数才能调用该构造函数模板。根本不清楚您要实现的目标。
回答by KeatsPeeks
You can create a templated factory function:
您可以创建模板化工厂函数:
class Foo
{
public:
template <class T> static Foo* create() // could also return by value, or a smart pointer
{
return new Foo(...);
}
...
};
回答by Johannes Schaub - litb
As far as I understand, it's impossible to have it (because it would conflict with the default constructor - am I right?)
据我了解,不可能拥有它(因为它会与默认构造函数冲突 - 我对吗?)
You are wrong. It doesn't conflict in any way. You just can't call it ever.
你错了。它不以任何方式冲突。你永远不能打电话给它。
回答by Yakk - Adam Nevraumont
template<class...>struct types{using type=types;};
template<class T>struct tag{using type=T;};
template<class Tag>using type_t=typename Tag::type;
the above helpers let you work with types as values.
上面的助手让您可以将类型作为值处理。
class A {
template<class T>
A( tag<T> );
};
the tag<T>
type is a variable with no state besides the type it caries. You can use this to pass a pure-type value into a template function and have the type be deduced by the template function:
的tag<T>
类型与除它以外龋类型没有状态的变量。您可以使用它来将纯类型值传递给模板函数,并由模板函数推导出类型:
auto a = A(tag<int>{});
You can pass in more than one type:
您可以传入不止一种类型:
class A {
template<class T, class U, class V>
A( types<T,U,V> );
};
auto a = A(types<int,double,std::string>{});
回答by Armen Tsirunyan
Some points:
几点:
- If you declare anyconstructor(including a templated one), the compiler will refrain from declaring a default constructor.
- Unless you declare a copy-constructor (for class X one
that takes
X
orX&
orX const &
) the compiler will generate the default copy-constructor. - If you provide a template constructor for class X which takes
T const &
orT
orT&
then the compiler will nevertheless generate a default non-templated copy-constructor, even though you may think that it shouldn't because when T = X the declaration matches the copy-constructor declaration. - In the latter case you may want to provide a non-templated copy-constructor along with the templated one. They will not conflict. When X is passed the nontemplated will be called. Otherwise the templated
- 如果您声明任何构造函数(包括模板化的构造函数),编译器将避免声明默认构造函数。
- 除非您声明一个复制构造函数(对于 X 类,它采用
X
orX&
或X const &
),否则编译器将生成默认的复制构造函数。 - 如果您为类 X 提供了一个模板构造函数,它采用
T const &
orT
或T&
然后编译器将生成一个默认的非模板化复制构造函数,即使您可能认为它不应该,因为当 T = X 时,声明与复制构造函数匹配宣言。 - 在后一种情况下,您可能希望提供一个非模板化的复制构造函数以及模板化的复制构造函数。他们不会冲突。当 X 被传递时,非模板化将被调用。否则模板化
HTH
HTH
回答by Tolli
You could do this:
你可以这样做:
class C
{
public:
template <typename T> C(T*);
};
template <typename T> T* UseType()
{
static_cast<T*>(nullptr);
}
Then to create an object of type C
using int
as the template parameter to the constructor:
然后C
使用int
作为构造函数的模板参数创建一个类型的对象:
C obj(UseType<int>());
Since you can't pass template parameters to a constructor, this solution essentially converts the template parameter to a regular parameter. Using the UseType<T>()
function when calling the constructor makes it clear to someone looking at the code that the purpose of that parameter is to tell the constructor what type to use.
由于您无法将模板参数传递给构造函数,因此该解决方案本质上是将模板参数转换为常规参数。UseType<T>()
在调用构造函数时使用该函数可以让查看代码的人清楚该参数的目的是告诉构造函数使用什么类型。
One use case for this would be if the constructor creates a derived class object and assigns it to a member variable that is a base class pointer. (The constructor needs to know which derived class to use, but the class itself doesn't need to be templated since the same base class pointer type is always used.)
一个用例是如果构造函数创建派生类对象并将其分配给作为基类指针的成员变量。(构造函数需要知道要使用哪个派生类,但类本身不需要模板化,因为始终使用相同的基类指针类型。)
回答by user2616927
try doing something like
尝试做类似的事情
template<class T, int i> class A{
A(){
A(this)
}
A( A<int, 1>* a){
//do something
}
A( A<float, 1>* a){
//do something
}
.
.
.
};
回答by Syncopated
Here's a workaround.
这是一个解决方法。
Make a template subclass B of A. Do the template-argument-independent part of the construction in A's constructor. Do the template-argument-dependent part in B's constructor.
创建 A 的模板子类 B。在 A 的构造函数中执行与模板参数无关的构造部分。在 B 的构造函数中做模板参数相关的部分。