[英]Specialized constructor for template class
Suppose that there are 3 classses: 假设有3个类别:
template <typename T>
class X;
template <typename T>
class Y;
template <typename T>
class Z;
I wish to define a constructor for X
which takes an object reference of type Z<T>
and returns an object of type X<Y<T>>
. 我希望为
X
定义一个构造函数,该构造函数采用Z<T>
类型的对象引用并返回X<Y<T>>
类型的对象。 Is this possible with a single template definition? 单个模板定义可以做到吗?
template <typename T>
X<Y<T>>::X(Z<T>) {
// logic to map Z<T> to Y<T> and pass it on for object creation.
}
I guess there will be significant side-effects if I use two template definitions for defining the constructor. 我想如果我使用两个模板定义来定义构造函数,将会产生明显的副作用。
Something like this? 像这样吗
template <class T>
class Z;
template <class T>
class Y;
template <class T>
class X
{
X(Z&);
};
template<class T>
X<Y<T>> MakeX(Z<T>& z)
{
return X<Y<T>>(z);
};
I am not sure whether you can accomplish what you want to using a single template class. 我不确定您是否可以使用单个模板类来完成所需的工作。 However, you can use template specialization to accomplish what you are looking for.
但是,您可以使用模板专业化来完成所需的工作。
Here's a minimal definition of such a class. 这是此类的基本定义。
template <typename T> class X
{
};
template <typename T> class Y
{
};
template <typename T> class Z
{
};
template <typename T> class X<Y<T> >
{
public:
X(Z<T> z) {}
};
int main()
{
Z<int> z;
X<Y<int> > x(z);
}
Direct way to achieve this: 实现此目的的直接方法:
template <typename T>
class Y{};
template <typename T>
class Z{};
template <typename T>
class X
{
template <typename U>
X(U){}
};
template <typename T>
template <>
X<Y<T>>::X(Z<T>){}
Unfortunately, this code is not standard-compliant. 不幸的是,该代码不符合标准。
If you really don't want to use a helper function ( @Neil Kirk 's variant ) or specialize a whole class ( @R Sahu 's variant ) you may try the following variant using std::enable_if
: 如果您真的不想使用辅助函数( @Neil Kirk的变体 )或专门研究整个类( @R Sahu的变体 ),则可以使用
std::enable_if
尝试以下变体:
#include <type_traits>
template <typename T>
struct template_traits;
template
<
template <typename>
class C,
typename A
>
struct template_traits<C<A>>
{
using argument_type = A;
};
template
<
typename T,
template <typename>
class C
>
struct is_instantiation_of : std::false_type{};
template
<
typename A,
template <typename>
class C
>
struct is_instantiation_of<C<A>, C> : std::true_type{};
template <typename T>
class Y{};
template <typename T>
class Z{};
template <typename T>
class X
{
public:
X(){}
template
<
typename U = T,
typename = typename std::enable_if<is_instantiation_of<U, Y>::value>::type
>
X(Z<typename template_traits<U>::argument_type>& z){}
};
Example of using: 使用示例:
Y<int> y_i;
Y<char> y_c;
Z<int> z_i;
Z<char> z_c;
X<int> x; // compiles
X<Y<int>> x1(z_i); // compiles
X<Y<int>> x2(z_c); // doesn't compile
X<Z<int>> x3(y_i); // doesn't compile
X<Z<int>> x4(y_c); // doesn't compile
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.