![](/img/trans.png)
[英]Is it good practice to move common code to base class assuming there is none?
[英]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.