2012-08-14 55 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