2017-04-07 106 views
1

派生类我有一系列的实地验证每一个看起来像下面的:存储模板集装箱

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

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

}; 

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

我想创建一个管理员类,作为这些验证器中的每一个的公共网关。类似如下:

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>()); 
... 

虽然这显然是乱码。

问题:

  • 有没有人用这种模式之前,并有实现这一目标的解决方案?
  • 我应该重新考虑这个设计吗?
+0

很可能有一个数组和遍历这一点。 – chris

+0

为什么特殊的验证器例如NameValidator是一个模板?它不应该来自Validator 或它应该验证的任何类型吗? – ZivS

+0

@chris - 你能澄清你的意思吗? – Ryan

回答

0

如果你想有一个容器,你可以吃的指令就像

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

你需要你的类型T是已知的,othewise NameValidator<T>不是一个类型,NameValidator<T>()无法初始化的对象。

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

所以,希望可以semplified,我能想象的最好的是在下面的例子中

#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"); 
}