我已经实施了一个简单的any
类和一个合适的visitor
类。这在功能级别上非常有用。但是当我尝试将访问者用作类中的成员时,会找到已注册的成员函数,但是没有输入。
这是一种我不理解的奇怪行为
我用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;
}
答案 0 :(得分:0)
您正在存储对临时的引用,其中包含所有未定义的行为
register_visitor
中的lambda函数需要按值捕获f
。