2013-02-27 22 views
5

Piszę bibliotekę, która wiąże się z dużą ilością oszustw szablonowych i boost :: any. Zabrakło mi w sytuacji, gdy mają zasadniczo to:doładowanie :: any i szablony

boost::any a1, a2, a3, a4; 

... i muszę wywołać funkcję, która wygląda tak:

template <typename A1, typename A2, typename A3, typename A4> 
void somefunc (A1 a1, A2 a2, A3 a3, A4 a4); 

mogłem uciekać się do nieprzyzwoicie zagnieżdżonych serii instrukcji if, ale zakładając, że obsługuję 10 różnych typów, to 10 000, jeśli instrukcje! Zwiększenie preprocesora może pomóc, ale to wciąż jest straszne rozwiązanie.

Czy istnieje lepszy sposób wywoływania funkcji szablonowej z zawartością boostu :: any bez uciekania się do tego rodzaju szaleństwa? O ile mogę powiedzieć, nie ma.

+0

Tylko użytkownik z następujących 'boost :: any' instancja może uzyskać dokładną wartość w czasie wykonywania (dostarczając typ zakodowany), nie możesz wywołać tej funkcji z wartością zawartą w 'boost :: any', ponieważ jej typ został * wymazany * podczas kompilacji. Jaki jest większy problem, który próbujesz rozwiązać? 'boost :: any' to rzeczy dość niskiego poziomu. – GManNickG

+3

Mieć wszystkie obiekty "jakikolwiek" jako jeden obiekt, a przy ustawianiu ich wszystkich na raz, również bezpieczny wskaźnik do prawidłowej instancji 'somefunc' (np.' & Somefunc '). – Xeo

+0

@GManNickG większy problem, który próbuję rozwiązać, polega na automatycznym generowaniu powiązań Lua po jednej stronie i zwiększeniu :: dowolnym zatrzymaniu wyniku z dowolnej asynchronicznej funkcji. W tej sytuacji nie można zastąpić drugiej. – Xtapolapocetl

Odpowiedz

10

Jeśli wszystkie obiekty any można ustawić w tym samym czasie, można po prostu zakodować kod typu wskaźnika funkcji wtedy i tam. Wypakuj to wszystko w oddzielny obiekt i możesz już iść. To jest w zasadzie dwukrotnie podjąć type-erasure, a może być również realizowane za pośrednictwem wirtualnych funkcji (takich jak boost::any pracuje wewnętrznie), ale podoba mi się ta wersja więcej:

// note that this can easily be adapted to boost::tuple and variadic templates 
struct any_container{ 
    template<class T1, class T3, class T3> 
    any_container(T1 const& a1, T2 const& a2, T3 const& a3) 
    : _ichi(a1), _ni(a2), _san(a3), _somefunc(&somefunc<T1, T2, T3>) {} 

    void call(){ _somefunc(_ichi, _ni, _san); } 

private: 
    boost::any _ichi, _ni, _san; 
    // adjust to your need 
    typedef void (*func_type)(boost::any&, boost::any&, boost::any&); 
    func_type _somefunc; 

    template<class T1, class T2, class T3> 
    void somefunc(boost::any& a1, boost::any& a2, boost::any& a3){ 
    // access any objects with 'boost::any_cast<TN>(aN)' 
    } 
}; 
+0

Świetne, dziękuję. – Xtapolapocetl

+0

+1, szczególnie dla zmiennych _ichi, _ni i _san. –