简体   繁体   English

模板类的专门构造函数

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM