c++ - 派生类模板

标签 c++ templates derived-class

我对派生类模板有一些疑问。我有这样的基类和派生类模板:

// This is base class
class CParameter {
public:
   CParameter(std::string name) : name(name) {}
// virtual ~CParameter() {} // deleted for good design:)

public:
   std::string name;
};

...

// This is derived class
template <typename T>
class CTemplateParameter : public CParameter {
public:
   CTemplateParameter(std::string name) : CParameter(name) {}
public:
   T parameter;
};

我声明了一些类型参数并将它们推送到基类 vector

//Base class parameters
std::vector<CParameter*> parameters; // !
CTemplateParameter<CMatrix4<float>> mat4;
CTemplateParameter<CVector3<float>> vec3;
CTemplateParameter<float> flt;

parameters.push_back(mat4);
parameters.push_back(vec3);
parameters.push_back(flt);

我有模板 SetParameter 函数:

// This method moved to CParameter base class
template <typename T>
bool SetParameter(const CTemplateParameter<T>& param) {
// switch(typeof(T)) {
// set parameter
if (std::is_same<T, int>::value)
   // gLUniform1i(...)
else if (std::is_same<T, CMatrix4<float>>::value)
   // glUniformMatrix4fv(..)
...

所以我的问题:

1)如何单独设置所有参数?

// Notice this function is not template
void SetAll() {
   for each parameter
      SetParameter(parameter[i])
}

2) 如果没有枚举,我可以获取参数类型并在运行时创建类型吗?喜欢:

Pseudo code:
    //get type of parameter[i]
    //create a parameter from
    T type = GetTypeofParameter(parameter[i]);
    CTemplateParameter<type> newType;

3) 我能否得到这样的派生类类型或如何转换?

CTemplateParameter<void*>* p = dynamic_cast<CTemplateParameter<void*>>(parameters[i]);

非常感谢。

最佳答案

我的评论似乎已将 ADesignersEncyclopedia 推离了模板/虚拟组合,但没有推向实用的替代方案。最初的问题没有提供足够的信息来决定是否有实际的选择。缺乏这样一个实用的替代方案,正确地进行虚拟/模板混合(使用 CRTP)而不是完全拒绝它:

在您的目标类中,您需要两种形式的 setParameter,这两种形式都不是模板。第一种形式分派(dispatch)到参数类中的 setParameter,它分派(dispatch)回目标类中的第二种形式:

bool SetParameter(const CParameter& param) {
   return param.SetParameter( *this );
}

第二种形式重载了值类型:

bool SetParameter(int value) {
   // whatever
}
bool SetParameter(CMatrix4<float> const& value) {
   // whatever
}
...

在你的参数基类中,你想要 SetParameter 纯虚拟

class CParameter
{
    ...
    virtual bool SetParameter( TargetType& ) const = 0;
    ...
};

然后您需要一个 CRTP 基类,它应该派生自您的简单基类:

template<class ActualType>
class CRTPParameter : public CParameter
{
  CRTPParameter(std::string name) : CParameter(name) {}
  ActualType* This() {return static_cast<ActualType*>(this); }
  ActualType const* This() const {return static_cast<ActualType const*>(this); }
  // various things including
  ActualType* clone() const { return new ActualType( *This() ); }
  bool SetParameter( TargetType& target ) const
  { return target.SetParameter( This()->parameter ); }
};

然后您的模板类派生自您的 CRTP 类

template <typename T>
class CTemplateParameter : public CRTPParameter<CTemplateParameter<T> > {
public:
   typedef CRTPParameter<CTemplateParameter<T> super;
   CTemplateParameter(std::string name) : super(name) {}

如果其他一切都足够简单,那么整个 CRTP 方案可能会过大,您可以将 clone 和 SetParameter 从 CRTPParameter 移动到 CTemplateParameter 并返回到没有 CRTPParameter。

但根据我对此类结构的经验,CTemplateParameter 中的事情很快就会变得困惑,最好由额外的层来处理。

关于c++ - 派生类模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33737032/

相关文章:

c++ - 对C++中的char指针的困惑

c++ - 适用于 Windows Mobile 的 OpenGL ES 2.0 SDK

c++ - 如何将所有结构成员设置为相同的值?

typescript - vuejs 计算属性和模板调试有什么好办法吗?

c++ - 部分排序期间成员函数模板的原始类型是什么

c++ - 从派生类访问基类中的 protected 成员

c++ - 如何设置二维窗口

c++ - 没有形式参数的可变函数模板

c++ - 为什么派生模板类不能访问基模板类的标识符?

python - 为什么从字典派生的类不显示包含键