使用 boost::variant 并获取泛型返回类型
Using boost::variant and getting a generic return type
我正在寻找如何重构这段代码的想法或关于我是否过度思考它的意见。请考虑以下boost::variant
using Pattern = boost::variant<std::regex, MyOwnClass>;
现在这是我想做什么的想法:
Pattern pattern;
// do some stuff...
// see if the pattern matches some data
PatternVisitor pvisitor(dataBegin, dataEnd);
if (boost::apply_visitor(pvisitor, pattern))
{
// want to use pvisitor.matches generically inside here
// regardless of what variant pattern is
for (auto idx = 0; idx < pvisitor.matches.size(); idx)
{
// now use the match
std::string strMatch(pvisitor.matches[idx].first, pvisitor.matches[idx].second);
std::cout << strMatch << 'n';
}
}
那么,如何定义PatternVisitor
呢?我从实现std::regex
部分开始,并提出了类似的东西:
struct PatternVisitor : public boost::static_visitor<bool>
{
PatternVisitor(const char* sBegin, const char* sEnd)
: searchBegin(sBegin), searchEnd(sEnd)
{
}
bool operator()(const std::regex& regexp)
{
return std::regex_search(searchBegin, searchEnd, regmatches, regexp, std::regex_constants::match_continuous);
}
bool operator()(const MyOwnClass& myClass)
{
// save this implementation for later, return true for now
return true;
}
const char* searchBegin;
const char* searchEnd;
std::cmatch matches;
};
这很好,但是...MyOwnClass
呢?我的第一个想法是我可以自己填充std::cmatch
但这似乎是不可能的,也不是一个好主意。因此,我当前的解决方案是这样的:
struct PatternVisitor : public boost::static_visitor<bool>
{
PatternVisitor(const char* sBegin, const char* sEnd)
: searchBegin(sBegin), searchEnd(sEnd)
{
}
bool operator()(const std::regex& regexp)
{
std::cmatch regmatches;
if (std::regex_search(searchBegin, searchEnd, regmatches, regexp, std::regex_constants::match_continuous))
{
for (const auto& m : regmatches)
{
matches.push_back(std::make_pair(m.first, m.second));
}
}
return !matches.empty();
}
bool operator()(const MyOwnClass& format)
{
// now I can just populate matches as needed
return true;
}
const char* searchBegin;
const char* searchEnd;
std::vector<std::pair<const char*, const char*>> matches;
};
虽然这有效,但我不喜欢将我需要的数据从regmatches
复制到另一个向量中。
能够以通用方式使用生成的匹配项的同时重构这一点的好方法是什么?
您可以在访问者中应用您的函数,例如:
struct PatternVisitor : public boost::static_visitor<bool>
{
PatternVisitor(const char* sBegin,
const char* sEnd,
std::function<void (const char*, const char*)> f)
: searchBegin(sBegin), searchEnd(sEnd), f(f)
{
}
bool operator()(const std::regex& regexp)
{
std::cmatch regmatches;
if (std::regex_search(searchBegin,
searchEnd,
regmatches,
regexp,
std::regex_constants::match_continuous)) {
for (const auto& m : regmatches) {
f(m.first, m.second);
}
return true;
}
return false;
}
bool operator()(const MyOwnClass& myClass)
{
// save this implementation for later, return true for now
return true;
}
const char* searchBegin;
const char* searchEnd;
std::function<void (const char*, const char*)> f;
};
然后
Pattern pattern = /*...*/;
PatternVisitor pvisitor(dataBegin, dataEnd, [](const char* beg, const char* end)
{
std::string strMatch(beg, end);
std::cout << strMatch << 'n';
});
boost::apply_visitor(pvisitor, pattern);
相关文章:
- 如何在C++中返回没有模板的泛型类型?
- 从具有泛型返回类型的 crtp 基类调用派生类中的函数
- 获取模板函数/泛型 lambda 的唯一返回类型
- 将 int 转换为泛型模板类型
- C# 泛型 - 基于类型特征的重载
- 使用 boost::variant 并获取泛型返回类型
- 接受泛型列表类型对象的参数
- C++:如何使用泛型返回类型定义虚函数
- 在C++11中确定泛型返回类型时出错
- 检查泛型/模板类型
- 泛型抽象类型c++
- 在java中传递泛型类类型
- 用泛型返回类型专门化函数
- 为泛型数据类型创建自己的迭代器
- 尝试用c++类创建泛型数据类型的问题
- 如何在托管CLR的本地c++应用程序中创建泛型.net类型(不使用c++ /CLI)
- 具有泛型索引类型的数组
- 如何使用泛型返回类型重写虚拟函数
- 泛型JNI类型实例化
- 具有泛型指针类型的自链接类的类设计