我有一系列字段验证器,每个都类似于以下内容:
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/