繁体   English   中英

专门针对模板化模板参数的模板类构造函数

[英]Specialize template class constructor on templated template parameter

我试图找到一种方法来处理一些旧代码。 有一个模板化的类,我想让构造函数专门化,以便在使用某个参数实例化时将不同的参数传递给它的基数。

template<typename T, typename U>
class A : public U {
public:
    A(T &t, bool b);
    // Other member functions
}

template<typename T, typename U>
A<T, U>::A(T &t, bool b) 
    : U(t, b) {}

U是某个(模板)类时,我需要更改此构造函数的行为。

template<typename Z>
class S;

template<typename T>
template<typename Z>
A<T, S<Z>>::A(T &t, bool b)
    : S<Z>(t, b, false) {}

这可能吗? 我知道,如果不重新定义新类,就无法完成类模板专业化。 但是,我只想专门研究这种行为,而不要专门研究此类U任何其他成员函数。

您可以在每个类中添加一个名为id的函数,每个类的id函数将返回不同的值。 然后,您可以传入类型的id函数返回的内容。

如果您不想专门研究此类,则可以专门研究一个继承的类:

template<typename T, typename U>
class A_impl : public U {
public:
    A_impl(T &t, bool b) : U(t, b) { }
};

template<typename T, typename Z>
class A_impl<T,S<Z> > : public S<Z> {
public:
    A_impl(T &t, bool b) : S<Z>(t, b, false) { }
};

template<typename T, typename U>
class A : public A_impl<T,U> {
public:
    using A_impl<T,U>::A_impl; // C++11 : inherit A_impl's constructor here
    A(T &t, bool b) : A_impl<T,U>(t, b) {} // or C++98 calling it
};

C ++ 11解决方案可以基于SFINAE:如果U是不是基于S的类型,则启用第一个或第二个构造函数。

为此,开发类型特征以检测类型是否基于S是有用的。 举个例子

template <typename>
struct isS : public std::false_type
 { };

template <typename T>
struct isS<S<T>> : public std::true_type
 { };

使用isS ,您可以按以下方式编写构造函数(在A类的主体中)

template <typename V = U>
A(T & t, bool b,
  typename std::enable_if<false == isS<V>::value>::type * = nullptr )
   : U(t, b)
 { std::cout << "generic A constructor" << std::endl; }

template <typename V = U>
A(T & t, bool b,
  typename std::enable_if<true == isS<V>::value>::type * = nullptr)
   : U(t, b, false)
 { std::cout << "S specific A constructor" << std::endl; }

如果需要S的模板参数,则可以如下定义isS

template <typename T>
struct isS<S<T>> : public std::true_type
 { using type = T; };

并将其用作typename isS<V>::type

一个完整的工作示例

#include <vector>
#include <iostream>
#include <type_traits>

template <typename T>
struct S
 { 
   S (T const &, bool, bool)
    { std::cout << "S constructor" << std::endl; }
 };

template <typename>
struct isS : public std::false_type
 { };

template <typename T>
struct isS<S<T>> : public std::true_type
 { };

template <typename T, typename U>
struct A : public U
 {
   template <typename V = U>
   A(T & t, bool b,
     typename std::enable_if<false == isS<V>::value>::type * = nullptr )
      : U(t, b)
    { std::cout << "generic A constructor" << std::endl; }

   template <typename V = U>
   A(T & t, bool b,
     typename std::enable_if<true == isS<V>::value>::type * = nullptr)
      : U(t, b, false)
    { std::cout << "S specific A constructor" << std::endl; }
 };

int main ()
 {
   long l { 0L };

   // print "generic A constructor"
   A<long, std::vector<int>> alv(l, true);

   // print "S constructor>" and "S specific A constructor"
   A<long, S<int>>           als(l, true);
 }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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