2012-01-11 16 views
5

Bazı argümanlarla başka bir işlev (veya functor), f çağıran marshal_and_apply, bir işlev yapıyorum bir uygulama var. marshal_and_apply 'un görevi, f parametresinin türüne bağlı olarak argümanlar için bazı özel marshaling uygulamaları yapmaktır. f sitesindeki parametrelerden biri özel bir türü, marshal_me<T> arasında iseBir fonksiyonun parametrelerinin türleri nasıl denetlenir?

, daha sonra marshal_and_applyf geçirmeden önce, bazı özel ayrılmış depolama yoluyla parametre sıralamakta olacaktır. Tahsisi gerçekleştirmek için, tüm parametrelerin depolama gereksinimleri, herhangi bir sıraya girmeden önce marshal_and_apply ile bilinmelidir.


Bazı örnekler:

template<typename Function, typename... Args> 
void marshal_and_apply(Function f, Args... args); 

void func1(int x, int y); 
void func2(marshal_me<int> x, int y); 
void func3(marshal_me<int> x, marshal_me<int> y, marshal_me<int> z); 

// this call would be equivalent to: 
// func1(7,13) 
marshal_and_apply(func1, 7, 13); 

// this call would be equivalent to: 
// auto storage = my_allocator(sizeof(int)); 
// auto x = marshal_me<int>(7, storage); 
// func2(x, 13); 
marshal_and_apply(func2, 7, 13); 

// this call would be equivalent to: 
// auto storage = my_allocator(sizeof(int) + sizeof(int) + sizeof(int)); 
// auto x = marshal_me<int>(7, storage); 
// auto y = marshal_me<int>(13, storage + sizeof(int)); 
// auto z = marshal_me<int>(42, storage + sizeof(int) + sizeof(int)); 
// func3(x,y,z); 
marshal_and_apply(func3, 7, 13, 42); 

Bu sorunu çözmek için, marshal_and_applyf 'in parametre türlerini incelemek için bir mekanizma gerektirir gibi görünüyor. Bunun genel olarak mümkün olmadığına inanıyorum, ancak özel bir tür kümeden birinin (bu durumda, marshal_me<T>) belirli bir parametrenin türüne dönüştürülebilir olup olmadığını tanımak mümkün olabilir.

marshal_and_apply nasıl oluşturmalıyım?

+0

İkinci örneğinizde, "7" ile yaptığınızı göremiyorum. Bunu mu demek istediniz: auto x = marshal_me (storage, 7); 'ya da bir şey mi? –

+0

@AaronMcDaid Evet, düzeltdim. –

+0

Eğer marshal_me '' int 'bir' '' '' func2 (7, 13) 'çağırabilir '' bir kurucuya sahipse. Sarıcı hangi ek faydasıdır? –

cevap

4

Belki böyle bir şey: Artık

template<typename Function, typename... Args> 
void marshal_and_apply(Function f, Args &&... args) 
{ 
    f(InspectAndModify<Args>::process(sizeof...(Args), std::forward<Args>(args))...); 
} 

tanımlayın:

template <typename T> struct InspectAndModify 
{ 
    static T&& process(unsigned int N, T && t) 
    { 
     return std::forward<T>(t); 
    } 
}; 

template <typename T> struct InspectAndModify<marshal_me<T>> 
{ 
    static T&& process(unsigned int N, marshal_me<T> && m) 
    { 
     /* ... */ 
    } 
}; 

tamamen farklı bir şey: Bu yaklaşım ilk olarak işlev imzayı masaya ve bir "statik dönüşümü gerçekleştirir "marshal_me özelleştirmesini uygulayabileceğiniz her türden bir çift:

template <typename T> struct marshal_me { marshal_me(T) { } }; 

template <typename To, typename From> struct static_transform; 

template <typename T> struct static_transform<T, T> 
{ 
    static T go(T t) { return t; } 
}; 

template <typename T> struct static_transform<T, T&> 
{ 
    static T go(T & t) { return t; } 
}; 

template <typename T> struct static_transform<marshal_me<T>, T> 
{ 
    static marshal_me<T> go(T && t) { return std::forward<T>(t); } 
}; 

template<typename T, typename... Args> 
struct marshal_impl 
{ 
    template <typename ...Urgs> 
    static T go(T(*f)(Urgs...), Args &&... args) 
    { 
    return f(static_transform<Urgs, Args>::go(std::forward<Args>(args))...); 
    } 
}; 

template<typename Function, typename... Args> 
void marshal_and_apply(Function f, Args &&... args) 
{ 
    marshal_impl<void, Args...>::go(static_cast<typename std::decay<Function>::type>(f), 
            std::forward<Args>(args)...); 
} 
+0

Teşekkürler! Bu bir tür iş olacak, ama korkarım üçüncü örneği çözmeyecek. '' 'InspectAndModify :: process''', bunlardan herhangi birini işleyebilmeden önce işlemesi gereken toplam parametre sayısını bilmelidir. –

+0

@JaredHoberock: "sizeof ... (Args)" işlevini ek bir parametre olarak iletir misiniz? –

+0

Hangi işleve? 'Marshal_and_apply''' imzası düzeltildi, ancak' '' InspectAndModify :: process''' için fazladan bilgi aktarılabilir. –

İlgili konular