gpt4 book ai didi

c++ - 使用 boost::variant 并获取通用返回类型

转载 作者:行者123 更新时间:2023-11-28 04:57:44 27 4
gpt4 key购买 nike

我正在寻找有关如何重构此代码的想法或有关我是否过度思考的意见。考虑以下 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 复制到另一个 vector 中。

在能够以通用方式使用生成的匹配项的同时重构它的好方法是什么?

最佳答案

您可以在访问者内部应用您的功能,例如:

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++ - 使用 boost::variant 并获取通用返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46795025/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com