在boost :: static_visitor中operator()中的其他参数

Additional argument in operator() in boost::static_visitor

本文关键字:其他 参数 operator static visitor boost      更新时间:2023-10-16

我必须创建boost::variant对象并使用static_visitor。不幸的是我需要额外的参数...

哪种解决方案更好?要将这个对象作为类的字段,当我想使用访问者时,我必须创建实例:

class Visitor : public boost::static_visitor<>
{
public:
    Visitor(int extra): extra{extra} {}
    void operator()(const T1&) { /* ... */}
    void operator()(const T2&) { /* ... */}
private:
    int extra;
};

并每次我想使用它时创建访客对象:

Visitor visitor(x);
boost::apply_visitor(visitor, t);

或使用boost ::绑定并创建访客一次并使用boost::bind

class Visitor : public boost::static_visitor<>
{
public:
    void operator()(const T1&, int extra) { /* ... */ }
    void operator()(const T2&, int extra) { /* ... */ }
};

用法:

auto visitor = std::bind(SctpManager::Visitor(), std::placeholders::_1, extra);
boost::apply_visitor(visitor, t);

什么更好(更快,更优雅)解决方案?

或有更好的解决方案?

本质上没有更优雅的方式。您可以使用lambdas(如果您的编译器/Boost版本足够现代)。

"低技术"选项是使用保持状态的结构(第三个示例):

活在coliru

#include <boost/variant.hpp>
#include <iostream>
struct T1{};
struct T2{};
struct Visitor : boost::static_visitor<>
{
    void operator()(T1 const&, int extra) const { std::cout << __PRETTY_FUNCTION__ << " extra:" << extra << "n"; }
    void operator()(T2 const&, int extra) const { std::cout << __PRETTY_FUNCTION__ << " extra:" << extra << "n"; }
};
int main() {
    boost::variant<T1, T2> tests[] = { T1{}, T2{} };
    {
        Visitor vis;
        for (auto v: tests)
            apply_visitor([=](auto const& v) { vis(v, 42); }, v);
    }
    {
        auto vis = [vis=Visitor{}](auto const& v) { vis(v, 1); };
        for (auto v: tests)
            apply_visitor(vis, v);
    }

    {
        struct {
            using result_type = void;
            int extra;
            void operator()(T1 const&) const { std::cout << __PRETTY_FUNCTION__ << " extra:" << extra << "n"; }
            void operator()(T2 const&) const { std::cout << __PRETTY_FUNCTION__ << " extra:" << extra << "n"; }
        } vis { 99 };
        for (auto v: tests)
            apply_visitor(vis, v);
    }
}

打印

void Visitor::operator()(const T1&, int) const extra:42
void Visitor::operator()(const T2&, int) const extra:42
void Visitor::operator()(const T1&, int) const extra:1
void Visitor::operator()(const T2&, int) const extra:1
void main()::<unnamed struct>::operator()(const T1&) const extra:99
void main()::<unnamed struct>::operator()(const T2&) const extra:99