当我使用许多模板化的类并从它们派生时,我最近发现了"发明"这个简单的结构.我不确定这是不是常见的做法,还是我在脖子上系绳子.
template <typename T> class Base {};
template <typename T> class Derived : public Base<T>{
  typedef Base<T> Base;
};
Run Code Online (Sandbox Code Playgroud)
我发现如果Base类typedef对某些类型有自己的s,它会特别有用.例如:
template <typename T> class Base {
  typedef T Scalar;
  typedef Matrix<Scalar> Matrix;
};
Run Code Online (Sandbox Code Playgroud)
然后很容易"导入"类型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
};
Run Code Online (Sandbox Code Playgroud)
另外一个很大的优点是,当你想在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;
}
Run Code Online (Sandbox Code Playgroud)
有很多东西,代码变得非常臃肿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]
Run Code Online (Sandbox Code Playgroud)
(注意:这是指最初发布的简化示例,并未涵盖基类名称在不同范围内的更新问题.)
小智 1
实际上,如果 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
};
Run Code Online (Sandbox Code Playgroud)
        |   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           203 次  |  
        
|   最近记录:  |