重构使用其嵌套类作为另一个类的模板参数的模板类

虽然为了便于对现有代码库进行单元测试而重构代码,但我发现一个代码片段如下所示:

template <typename T>
class B {
 public:
  B(T* t) : t_(t) {}
  void do_that() { t_->do_abc(); }

 private:
  T* t_;
};

template <typename T1,typename T2>
class A {
 public:
  class NA {
   public:
    NA(A* a) : a_(a) {}
    void do_abc() { a_->do_xy(); }

   private:
    A* a_;
  };

  A(T1 t1,T2 t2) : t1_(t1),t2_(t2) {
    auto na = new NA(this);
    b_ = new B<NA>(na);
  }

  void do_this() { b_->do_that(); }
  void do_xy() { t1_.do_x(); t2_.do_y(); }

 private:
  T1 t1_;
  T2 t2_;
  B<NA>* b_;
};

简而言之:A取决于T1T2BB依赖于嵌套在NA中的ANA依赖于A

我想将B<NA>作为模板参数class A并将some b传递给A's constructor(就像T1T2一样)。

我首先尝试将NA移到A的外面,并同时将BNA的模板参数设为A,但它不能像NA取决于A(通过A* a_;a_->do_xy();)。

我应该做什么?

shuishuiwoai 回答:重构使用其嵌套类作为另一个类的模板参数的模板类

从技术上讲,您可以将NA用作模板:

template <class T>
class NA {
public:
    NA(T* a) : a_(a) {}
    void do_abc() { a_->do_xy(); }

private:
    T* a_;
};

但是,问题是,它是否可以正确表达您的设计意图。

,

使用模板template参数和工厂,您可以执行以下操作:

template <typename T1,typename T2,template <typename> class C = B>
class A {
public:
   class NA
   {
   public:
       NA(A* a) : a_(a) {}
       void do_abc() { a_->do_xy(); }

   private:
       A* a_;
   };

   template <typename Factory> // or possibly std::function<C<NA>*(A*)>
   A(T1 t1,T2 t2,Factory f) : t1_(t1),t2_(t2),b_(f(this)) {}

  void do_this() { b_->do_that(); }
  void do_xy() { t1_.do_x(); t2_.do_y(); }

 private:
    T1 t1_;
    T2 t2_;
    C<NA>* b_;
};

使用方式:

auto b_factory = [](A<MyType1,MyType2>* a){
        auto* na = new A<MyType1,MyType2>::NA(a);
        return new B<A<MyType1,MyType2>::Na>(na);
    };
MyType1 t1{/*...*/};
MyType2 t2{/*...*/};

A<MyType1,MyType2,B> a(t1,t2,b_factory)
,

NA依赖于A是没有理由不在A之外声明它。只需用A声明class A;。它是一个不完整的类型,但是拥有一个指针是没有问题的。您只需要在do_abc()的实际定义之后进行A的定义。但是在此之前声明是没有问题的。编辑:当然,这将使NA也显式依赖(它已经隐式地)依赖于T1T2,因此您必须将其用作{{ 1}}。

当然,您也可以将template template parameters和模板NA<T1,T2>A一起使用(对怪异的名称表示抱歉,但它们不应遮盖类)。

本文链接:https://www.f2er.com/2963910.html

大家都在问