2012-08-14 83 views
1

給定以下Anthony Williams的代碼片段。 一個非常基本的元組示例,這裏的所有內容都按預期工作。可變參數模板和參數推導

#include <iostream> 

template<typename ... Types> 
class simple_tuple; 

template<> 
class simple_tuple<> 
{}; 

template<typename First,typename ... Rest> 
class simple_tuple<First,Rest...>: 
     private simple_tuple<Rest...> 
{ 
     First member; 
public: 
     simple_tuple(First const& f,Rest const& ... rest): 
      simple_tuple<Rest...>(rest...), 
        member(f) 
      {} 
      First const& head() const 
      { 
        return member; 
      } 
      simple_tuple<Rest...> const& rest() const 
      { 
        return *this; 
      } 
}; 

template<unsigned index,typename ... Types> 
struct simple_tuple_entry; 

template<typename First,typename ... Types> 
struct simple_tuple_entry<0,First,Types...> 
{ 
     typedef First const& type; 
     static type value(simple_tuple<First,Types...> const& tuple) 
     { 
       return tuple.head(); 
     } 
}; 

template<unsigned index,typename First,typename ... Types> 
struct simple_tuple_entry<index,First,Types...> 
{ 
     typedef typename simple_tuple_entry<index-1,Types...>::type type; 
     static type value(simple_tuple<First,Types...> const& tuple) 
     { 
       return simple_tuple_entry<index-1,Types...>::value(tuple.rest()); 
     } 
}; 
template<unsigned index,typename ... Types> 
typename simple_tuple_entry<index,Types...>::type 
     get_tuple_entry(simple_tuple<Types...> const& tuple) 
{ 
     std::cout << "SizeofArgs == " << sizeof...(Types) << std::endl; 
     return simple_tuple_entry<index,Types...>::value(tuple); 
} 

int main() 
{ 
     simple_tuple<int,char,double> st(42,'a',3.141); 
     std::cout<<get_tuple_entry<0>(st)<<"," 
       <<get_tuple_entry<1>(st)<<"," 
       <<get_tuple_entry<2>(st)<<std::endl; 
} 

但我想知道get_tuple_entry函數。
我認爲可變參數模板參數的數量將每個呼叫有所不同,但總的sizeof返回3.
因此函數在某種程度上等同於以下(僞代碼)

template<unsigned index, <int,char,double> > 
typename simple_tuple_entry<index, <int,char,double> >::type 
     get_tuple_entry(simple_tuple<int,char,double> const& tuple) 
{ 
     std::cout << "SizeofArgs == " << sizeof...(<int,char,double>) << std::endl; 
     return simple_tuple_entry<index,<int,char,double> >::value(tuple); 
} 

但是,這將意味着那get_tuple_entry只是由不可能的返回值重載。爲什麼每個電話的簽名都不一樣?

回答

5

但是,這將意味着get_tuple_entry僅由返回值,這是不可能超載。

get_tuple_entry不是一個函數,它是一個函數模板。相同函數的三種重載只在返回類型上有所不同,它們所引用的內容並不相同。它們是函數模板的不同實例:

get_tuple_entry<0, int, char, double> 
get_tuple_entry<1, int, char, double> 
get_tuple_entry<2, int, char, double> 

它們不是相同的功能。

我認爲可變參數模板參數的數量將每個呼叫有所不同,但總的sizeof返回3

當然。每次調用該函數模板的實例化時,都會傳遞類型爲simple_tuple<int,char,double>的相同參數,因此每次將模板參數包推導爲大小爲3的int, char, double。調用之間的差異是您調用不同的實例化,並且get_tuple_entry<0>get_tuple_entry<1>不同,並且每個不同的實例返回元組的不同元素。

這是

#include <iostream> 

template<int N> 
void func() 
{ 
    std::cout << N << '\n'; 
} 

int main() 
{ 
    func<0>(); 
    func<1>(); 
    func<2>(); 
} 

這就要求打印不同的東西三個不同的功能真的沒有什麼不同,但有沒有問題,有相同的簽名,因爲func<0>()func<1>()func<2>()都是不同的功能。如果你看看這些有名字的名字,你會看到他們有不同的簽名,例如與G ++我得到_Z4funcILi0EEvv_Z4funcILi1EEvv_Z4funcILi2EEvv這是不相同的簽名。

+0

謝謝。特別是對於你的簡單例子。這真的打開了我的眼睛。 – mkaes 2012-08-14 14:34:03