2013-10-26 41 views
3

如果我有這樣的元組類型:穿越算法嵌套C++ 11元組

std::tuple<int, string, std::tuple<...>, int>

我怎麼能穿越嗎?我已經能夠編寫遍歷一個平面元組的函數,但不能嵌套元組。

這個問題似乎是處理所有可能的類型在嵌套元組模板化的功能或類型的任何實現,必須有這種情況:

template<typename T> 
void somefunc(T t) 
{ 
    // Do something to t 
} 

這最終成爲了最好的選擇每種類型的重載解析,並且你不能遞歸地遍歷元組,因爲你失去了它是一個元組的信息。如果你試圖編寫一個試圖確定它是否是一個元組的類或函數,你仍然會遇到與上面相同的問題的「false」情況,因爲它最終會匹配每個類型,而專用元組版本被忽視。

有沒有一種方法我不知道檢查是否是一個元組?

+0

你能在解釋你正在嘗試做的(僞)代碼?這個問題對我來說不是很清楚。 –

+2

正常重載應該很好。有什麼問題? –

+0

您想爲元組中的每個元素運行一次'some_func'?但是如果一個子元素*是一個元組,你想在它的每個元素上運行'some_func'而不是?遞歸地一直下降? –

回答

0

如果你想檢查類型T是否是一個元組,這應該工作:

#include <type_traits> 
#include <tuple> 

template<typename> struct is_tuple : std::false_type {}; 
template<typename... Ts> struct is_tuple<std::tuple<Ts...>> : std::true_type {}; 

static_assert(is_tuple<std::tuple<int>>::value, "Oops"); 
static_assert(!is_tuple<int>::value, "Oops"); 

int main() {} 
2

只需重載someFunc()功能的元組和非元組類型:

template<typename... Ts> 
void someFunc(const std::tuple<Ts...>& tuple) 
{ 
    /* traverse the elements of the tuple */ 
    traverse_tuple(tuple); 
} 

template<typename T> 
void someFunc(const T& value) 
{ 
    /* do something with the value */ 
} 

其中traverse_tuple是您實現的用於遍歷非嵌套(平面)元組的相同函數。它爲元組的每個成員調用someFunc()
對於元組遍歷函數的實現,您可以檢查this answer

0

您可以專注結構/類,而不是專業功能: 適應以下,以你的情況(http://ideone.com/VgIJfj):

namespace details 
{ 

template<std::size_t I = 0, typename FuncT, typename... Tp> 
inline typename std::enable_if<I == sizeof...(Tp), void>::type 
    for_each(const std::tuple<Tp...> &, FuncT) 
    { } 

template<std::size_t I = 0, typename FuncT, typename... Tp> 
inline typename std::enable_if<I < sizeof...(Tp), void>::type 
    for_each(const std::tuple<Tp...>& t, FuncT f) 
    { 
    f(std::get<I>(t)); 
    for_each<I + 1, FuncT, Tp...>(t, f); 
    } 

template <typename T> 
struct traverseType 
{ 
    void operator() (const T& t) const 
    { 
     std::cout << "it is a generic T:" << t << std::endl; 
    } 
}; 

template <> 
struct traverseType<int> 
{ 
    void operator() (int i) const 
    { 
     std::cout << "it is a int:" << i << std::endl; 
    } 
}; 

// needed by the for_each. 
struct traverseTypeCaller 
{ 
    template <typename T> 
    void operator() (const T& t) const 
    { 
     details::traverseType<T>()(t); 
    } 
}; 

template <typename ...T> 
struct traverseType<std::tuple<T...>> 
{ 
    void operator() (const std::tuple<T...>& t) const 
    { 
     std::cout << "it is a tuple:" << std::endl; 
     for_each(t, traverseTypeCaller()); 
    } 
}; 

} 

template <typename T> 
void traverseType(const T& t) 
{ 
    details::traverseTypeCaller()(t); 
}