이 코드는 https://gist.github.com/2945472입니다.하지만 C++ 11에 의존하지 않는 구현이 필요합니다. 나는 단지 부스트를 사용하기 위해 그것을 변환하는 것에 손을 썼다. 그러나 나는 약간의 문제가있다. 맵에 삽입 할 때 나는 bad_any_cast 받고 있어요방문자 패턴 boost :: any
#include <boost/any.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/unordered_map.hpp>
struct type_info_hash {
std::size_t operator()(std::type_info const & t) const {
return t.hash_code();
}
};
struct equal_ref {
template <typename T> bool operator()(boost::reference_wrapper<T> a,boost::reference_wrapper<T> b) const {
return a.get() == b.get();
}
};
struct any_visitor {
boost::unordered_map<boost::reference_wrapper<std::type_info const>, boost::function<void(boost::any&)>, type_info_hash, equal_ref> fs;
template <typename T> void insert_visitor(boost::function<void(T)> f) {
try {
fs.insert(std::make_pair(boost::ref(typeid(T)), boost::bind(f, boost::any_cast<T>(boost::lambda::_1))));
} catch (boost::bad_any_cast& e) {
std::cout << e.what() << std::endl;
}
}
bool operator()(boost::any & x) {
boost::unordered_map<boost::reference_wrapper<std::type_info const>, boost::function<void(boost::any&)>, type_info_hash, equal_ref>::iterator it = fs.find(boost::ref(x.type()));
if (it != fs.end()) {
it->second(x);
return true;
} else {
return false;
}
}
};
struct abc {};
void fa(int i) { std::cout << "fa(" << i << ")" << std::endl; }
void fb(abc) { std::cout << "fb(abc())" << std::endl; }
int main() {
any_visitor f;
f.insert_visitor<int>(fa);
f.insert_visitor<abc>(fb);
std::vector<boost::any> xs;
xs.push_back(1);
xs.push_back(abc());
xs.push_back(1.5);
for (auto & x : xs) {
if (!f(x)) std::cout << "no visitor registered" << std::endl;
}
}
: 여기
내가 생각 해낸 것입니다. any_cast를 it -> second (x)로만 호출하면 안됩니까? 내가 도대체 뭘 잘못하고있는 겁니까?
방문자가 상자에서 지원되는'boost :: variant'를 사용 해본 적이 있습니까? 'any '를 사용하면 타입이 타입 시스템의 * anything *, 즉 * all * 타입이 될 수 있다고 가정합니다. 'variant'는 객체에서 사용하고자하는 타입의 부분 집합이 있다고 가정합니다. 서로 다른 함수를 정의해야하므로 방문자는 '변형'에 더 가깝습니다. –
제 생각은 boost :: any를 사용하는 boost :: program_options에서 설정 파일을 작성하는 것입니다. – Keith