【问题标题】:Specialize template class constructor on templated template parameter在模板化模板参数上专门化模板类构造函数
【发布时间】:2017-07-21 13:51:23
【问题描述】:

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

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

【问题讨论】:

标签: c++ c++11 templates


【解决方案1】:

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&lt;V&gt;::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);
 }

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      如果你不想专门化这个类,你可以专门化你要继承的一个:

      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
      };
      

      【讨论】:

        猜你喜欢
        • 2016-07-02
        • 1970-01-01
        • 2015-03-12
        • 2014-10-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多