簡體   English   中英

typedeffing模板化基類是簡化代碼的一個好習慣嗎?

[英]Is typedeffing templated base class to simplify the code a good practice?

當我使用許多模板化的類並從它們派生時,我最近發現了“發明”這個簡單的結構。 我不確定這是不是常見的做法,還是我在脖子上系繩子。

template <typename T> class Base {};

template <typename T> class Derived : public Base<T>{
  typedef Base<T> Base;
};

我發現如果Base類對某些類型有自己的typedef特別有用。 例如:

template <typename T> class Base {
  typedef T Scalar;
  typedef Matrix<Scalar> Matrix;
};

然后很容易將“導入”類型導入到Derived 它可以節省重新鍵入模板簽名的麻煩。 例如:

template <typename T> class Derived : public Base<T>{
  typename Base<T>::Matrix yuck_yuck(); //that's what I am trying to simplify
  typedef typename Base<T> Base;
  typedef typename Base::Matrix Matrix;
  Matrix much_fun(); //looks way better
};

另外一個很大的優點是,當你想要另一個模板參數添加到Base類時。 您不必更改一堆函數,只需更新typedef much_fun如果不會有任何問題Base將被更改為Base<T,U>yuck_yuck將需要更新的簽名(不知道模板參數正式與簽名包括在內,所以請原諒我,如果我在這里做一個正式的錯誤,但我認為是)。

這是一個很好的做法,還是我在我的重要部位旁邊玩槍? 看起來它使代碼更具可讀性並簡化了它,但也許我錯過了一些可能適得其反的東西。

編輯2:我得到了工作實例。 Base類必須在其命名空間內,否則將在范圍內與相同的名稱發生沖突,如評論者指出的那樣。 以下是體現我真實問題的最小例子。

namespace Fun {
template <typename T> class Base {
public:
  typedef T Scalar;
};
}

template <typename T> 
class Derived : public Fun::Base<T>{
public:
  typedef typename Fun::Base<T> Base;
  typedef typename Base::Scalar Scalar;
  typename Fun::Base<T>::Scalar yuck_yuck();
  Scalar much_fun();
};

#include <iostream>
using namespace std;

int main() {
    Derived<double> d;
    return 0;
}

有很多東西,代碼變得非常臃腫與typenames和模板參數。 但是我已經在構成示例時遇到了麻煩,因為沒有將Base放在自己的命名空間中。 我想知道是否還有其他警告,這實際上是這個想法的殺手。

由於C ++ 11 3.3.7 / 1的規則2,我認為這是不正確的

在類S中使用的名稱N應在其上下文中引用相同的聲明,並在完成的S范圍內重新評估。

意味着您不能使用名稱Base來引用類范圍內的模板和typedef。 當然,我的編譯器不會接受它:

error: declaration of ‘typedef struct Base<T> Derived<T>::Base’ [-fpermissive]
error: changes meaning of ‘Base’ from ‘struct Base<T>’ [-fpermissive]

(注意:這是指最初發布的簡化示例,並未涵蓋基類名稱在不同范圍內的更新問題。)

如果typedef沒有公開或受到保護,我實際上認為這是一種有用(和良好)的做法:

// No template, not Base, to avoid that discussion
class Derive : public SomeBaseClass 
{
   private:
   typedef SomeBaseClass Base;

   public:
   typedef Base::T T;

   T f();
}; 

class MoreDerived : public Derived
{
   // Base is not accessible
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM