c++ - 在容器中存储模板化派生类

标签 c++ templates generics design-patterns

我有一系列字段验证器,每个都类似于以下内容:

template <typename T>
class NameValidator : public Validator<T> {

    ...
    bool validate(const T& msg) const override { ... }
    ...

};

这些验证器中的每一个都必须能够验证不同的消息类型,因此模板参数 T .

我想创建一个管理器类作为每个验证器的公共(public)网关。类似于以下内容:

class ValidatorManger {

    ...
    // Calls validate() functions for each field.
    template <typename T>
    bool validate(const T& msg) { ... }
    ...

};

因此,我需要将每个验证器类(例如:NameValidator<T>)存储在某种类型的数据结构中,然后在 ValidatorManager::validate() 中迭代它们.

有没有办法做到这一点,这样我就不必为每种消息类型明确专门化模板?我正在成像如下内容

validator_map.insert(std::make_pair("Name", NameValidator<T>));
validator_map.insert(std::make_pair("Age", AgeValidator<T>());
...

虽然这显然是胡言乱语。

问题:

  • 有没有人以前使用过这种模式并且有实现它的解决方案?
  • 我应该彻底重新考虑这个设计吗?

最佳答案

如果你想要一个容器,你可以按照这样的说明食用

validator_map.insert(std::pair("Name", NameValidator<T>()));
validator_map.insert(std::pair("Age", AgeValidator<T>()));

你需要你的类型T是已知的,否则NameValidator<T>不是类型并且 NameValidator<T>()无法初始化对象。

所以我想你的 validator_map应该是模板中的一个变量(静态的?)validator() ValidatorManager 中的方法.

所以,希望可以简化,我能想象的最好的是下面的例子

#include <set>
#include <vector>
#include <memory>
#include <iostream>

template <typename T>
struct Validator 
 { virtual bool validate (T const &) const = 0; };

template <typename T>
struct NameValidator : public Validator<T>
 {
   bool validate (T const & msg) const override
    { std::cout << "- name (" << msg << ")" << std::endl; return true; }
 };

template <typename T>
struct AgeValidator : public Validator<T>
 {
   bool validate (T const & msg) const override
    { std::cout << "- age  (" << msg << ")" << std::endl; return true; }
 };

struct ValidatorManager
 {
   template <typename T>
   bool validate (T const & msg) const
    {
      static bool first {true};
      static std::vector<std::unique_ptr<Validator<T>>> vvt;

      if ( first )
       {
         vvt.emplace_back( new NameValidator<T>{} );
         vvt.emplace_back( new AgeValidator<T>{} );

         first = false;
       }

      bool ret { true };

      for ( auto const & v : vvt )
         ret &= v->validate(msg);

      return ret;
    }
 };

int main()
 {
   ValidatorManager  vm;

   vm.validate(1);
   vm.validate(2.2);
   vm.validate("3.3");
 }

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

相关文章:

c# - 多态委托(delegate)

c++ - 连接到 MS VS 的 Cabal 库

c++ - 在cpp ros节点中使用外部类

C++模板C字符串参数

c++ - 将类模板声明为友元

c# - 我可以在 List<T> 中搜索特定值吗?

c++ - 用 C++ (OpenCV) 读取像素值

c++ - 使用 Qt 组件编译 C++ 代码

c++ - 用作函数参数时如何定义到类模板工作的转换

java - 在接口(interface)中使用泛型方法没有意义吗?