0
간단한 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;
}
아야! 간단했다. A는 거의 모든 곳에서 보였지만 시도하지 않은 시도 중 하나였습니다. 고마워요! – zussel