任何访问者都不能使用成员函数

any visitor doesn't work with member function

我实现了一个简单的 any class 和一个合适的 visitor class。这在功能级别上非常有效。但是,当我尝试将访问者用作 class 中的成员时,找到并调用了已注册的成员函数,但未输入。

这是一种我不理解的奇怪行为。
我用 gcc 5 和 6 试过了。
您可以在下方和 here 在线找到我的代码。

程序应该增加一个整数值。

#include <iostream>
#include <functional>
#include <typeindex>
#include <unordered_map>

// simple any class
struct any {
    ~any() { if(val) { deleter_(val); } }
    template < class T >
    any(const T &v)
        : val(new T(v))
        , deleter_(&destroy<T>)
        , indexer_(&index<T>)
    {}

    typedef void (*deleter)(void*);
    typedef std::type_index (*indexer)();

    template <typename T>
    static void destroy(void *p) { delete (T*)p; }
    template < class T >
    static std::type_index index() { return std::type_index(typeid(T)); }

    template < class T >
    T& as() { return *static_cast<T*>(val); }

    std::type_index type_index() const { return indexer_(); }

    void *val = nullptr;
    deleter deleter_ = nullptr;
    indexer indexer_ = nullptr;

};

struct any_visitor {
    using function = std::function<void(any&)>;

    template <typename T>
    void register_visitor(const std::function<void(T&)> &f) {
        fs.insert(std::make_pair(
          std::type_index(typeid(T)),
          function([&f](any & x) {
            f(x.as<T>());
          })
        ));
    }

    void visit(any & x) {
        auto it = fs.find(x.type_index());
        if (it != fs.end()) {
            it->second(x);
        }
    }

    std::unordered_map<std::type_index, function> fs;
};

struct processor  {
    // visitor as class member
    any_visitor visitor;

    processor() {
        // register member function
        visitor.register_visitor<int>([this](int &i) { this->process(i); });
    }

    void apply(any &a) { visitor.visit(a); }

    void process(int &val) { ++val; }
};

int main()
{
    any ai = 7;
    any aii = 10;

    // visitor inside a function
    any_visitor visitor;
    visitor.register_visitor<int>([](int &val) {
        ++val;
    });
    // increment works
    std::cout << "function before: " << aii.as<int>() << "\n";
    visitor.visit(aii);
    std::cout << "function after: " << aii.as<int>() << "\n";

    // increment doesn't work
    std::cout << "class before: " << ai.as<int>() << "\n";
    processor p;
    p.apply(ai);
    std::cout << "class after: " << ai.as<int>() << "\n";

    return 0;
}

您正在存储对临时对象的引用,其中包含未定义的行为。
register_visitor中的lambda函数需要按值捕获f