2016-11-28 28 views
0

在我的項目中,通過模板中定義找到一個元組的索引功能,通過我還是不明白它是如何工作: 似乎有一個遞歸,但我不知道它是如何終止權指數的想法?此模板如何工作以查找元組索引?

// retrieve the index (for std::get) of a tuple by type 
// usage: std::get<Analysis::type_index<0, Type, Types ...>::type::index>(tuple) 
// TODO: should make this tidier to use 
template<int Index, class Search, class First, class ... Types> 
struct type_index 
{ 
    typedef typename Analysis::type_index<Index + 1, Search, Types ...>::type type; 
    static constexpr int index = Index; 
}; 

template<int Index, class Search, class ... Types> 
struct type_index<Index, Search, Search, Types ...> 
{ 
    typedef type_index type; 
    static constexpr int index = Index; 
}; 
+3

我認爲相應的作者應該首先使用'TODO'... ;-) –

+1

如果「搜索」類型不在其中,則會生成*可愛*錯誤消息搜索... – Walter

回答

3

專業化是終止條件。請注意,它需要First等於Search

type_index<Index, Search, Search, Types ...> 
        ^^^^^^ ^^^^^^ 

例如,如果您有

type_index<0, C, A, B, C, D>, 

這不符合專業化,所以通用模板將被使用,重定向啓動(通過其type部件)

type_index<0, C, A, B, C, D>::type = type_index<1, C, B, C, D>::type 

但是這不可求值或者直到達到鏈

type_index<0, C, A, B, C, D>::type = ... = type_index<2, C, C, D>::type 

此時部分特可以被使用,它說,

type_index<2, C, C, D>::type = type_index<2, C, C, D> 
type_index<2, C, C, D>::index = 2 

type_index<0, C, A, B, C, D>::type::index = 2 
       ^^^^ 
       0 1 2 3 

如預期。


請注意,您不需要攜帶Index周圍,確實可以放下整個::type事情:

template<typename, typename...> 
struct type_index; 

template<typename Search, typename Head, typename... Tail> 
struct type_index<Search, Head, Tail...> { 
    // Search ≠ Head: try with others, adding 1 to the result 
    static constexpr size_t index = 1 + type_index<Search, Tail...>::index; 
}; 

template<typename Search, typename... Others> 
struct type_index<Search, Search, Others...> { 
    // Search = Head: if we're called directly, the index is 0, 
    // otherwise the 1 + 1 + ... will do the trick 
    static constexpr size_t index = 0; 
}; 

template<typename Search> 
struct type_index<Search> { 
    // Not found: let the compiler conveniently say "there's no index". 
}; 

這個工作過程:

type_index<C, A, B, C, D>::index 
    = 1 + type_index<C, B, C, D>::index 
    = 1 + 1 + type_index<C, C, D>::index 
    = 1 + 1 + 0 
    = 2 

,如果類型不在該列表中,會說像(GCC 6.2.1):

In instantiation of ‘constexpr const size_t type_index<X, C>::index’: 
    recursively required from ‘constexpr const size_t type_index<X, B, C>::index’ 
    required from ‘constexpr const size_t type_index<X, A, B, C>::index’ 
    required from [somewhere] 
error: ‘index’ is not a member of ‘type_index<X>’ 

我覺得很明顯。

+0

非常感謝,但我仍然有一些疑慮。 The'type_index <2, C, C, D>'可以同時匹配'模板'和'type_index <索引,搜索,搜索,類型...>',爲什麼編譯器選用第二一? –

+0

C++模板專業化(以及函數超載)解決方案都是關於什麼是最合適的。尋找 「偏序」[這裏](http://en.cppreference.com/w/cpp/language/partial_specialization)(和[這裏](http://en.cppreference.com/w/cpp/language/ function_template#Function_template_overloading))。 –

+0

對不起,應該說:上面的模板專門化解決方案的鏈接,[這裏](http://en.cppreference.com/w/cpp/language/overload_resolution)用於重載決議(「最佳可行功能」部分) 。 –