我一直在搜索SO和其他論壇尋找一種方法來確定lambda的參數和返回類型,然後對這些參數進行操作,以便對回購進行類型查找已經實例化的對象。重點是創建一種方法來對某些任意定義的lambda表達式執行依賴注入。舉例來說,如果我有類似如下:在模板類型上編譯時間循環
auto lambda = [] (MyObject o) -> string { return o.name(); };
我能確定的參數類型的拉姆達,並查找MyObject
類型的相應的對象,然後調用lambda
傳遞一個對象「自動地」。
到目前爲止,我已經找到方法來確定lambda表達式參數列表類型,並通過使用以下模板返回類型:
template <typename T>
struct function_traits
: public function_traits<decltype(&T::operator())>
{};
// For generic types, directly use the result of the signature of its 'operator()'
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) const>
// we specialize for pointers to member function
{
enum { arity = sizeof...(Args) };
// arity is the number of arguments.
typedef ReturnType result_type;
template <size_t i>
struct arg
{
typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
// the i-th argument is equivalent to the i-th tuple element of a tuple
// composed of those arguments.
};
};
我在this發現SO發佈(很整齊)。
現在,我願意做的事情,是實現某種編譯時當量以下的:
// first get the type of the lambda using the above 'function_traits' template
typedef function_traits<decltype(lambda)> traits;
// now iterate over the traits and get the type of each argument, then print out the type name
for (size_t i = 0u; i < size_t(traits::arity); ++i)
{
// The point to focus on here is `traits::args<i>::type`
std::cout << typeid(traits::args<i>::type).name() << std::end;
}
我上面張貼什麼是不可能的。上面的代碼中的問題是,i
不是一個常量,而是在運行時進行評估,而不是編譯時間(評估此模板魔法的其餘部分)。我嘗試了一些不同的方法來嘗試找出解決方法(其中的模板遞歸),但是我一直無法找到完全符合我需要的解決方案。
所以,我的問題的根源真的是,你如何「迭代」模板?我是TMP的新手,並且從運行時轉變爲編譯時邏輯一直具有挑戰性。如果任何人有一些建議,對於一個很棒的新手來說。
循環一般你可以acc用下面迭代的'template class Loop {...}'來代表'Loop ',並使用專門的'template class Loop {...}'來終止的情況下,但我不得不深入探討這個問題,以便弄清楚如何將其應用於這種情況。 –
cdhowie
2014-09-25 20:13:06
這個問題有兩種典型的方法:使用索引技巧進行遞歸和包擴展。你不會告訴我們遞歸有什麼問題,或者不幸的是你用遞歸嘗試了什麼。有關指數技巧,請參閱http://stackoverflow.com/a/7858971 – dyp 2014-09-25 20:25:25
你甚至可以在SO上找到幾個標題爲「迭代遍歷元組」或類似的問題,例如: http://stackoverflow.com/q/1198260 – dyp 2014-09-25 20:27:29