【问题标题】:Variadic templates and parameter deduction可变参数模板和参数推导
【发布时间】:2013-02-20 04:21:44
【问题描述】:

给定来自Anthony Williams 的以下代码sn-p。 一个非常基本的元组示例,这里的所有内容都按预期工作。

#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 仅被返回值重载,这是不可能的。为什么每次调用的签名都不同?

【问题讨论】:

    标签: c++ c++11 variadic-templates


    【解决方案1】:

    但这意味着 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&lt;int,char,double&gt; 类型的相同参数,因此每次模板参数包都推导出为大小为3 的int, char, double。调用之间的区别在于您调用了不同的实例化,而get_tuple_entry&lt;0&gt;get_tuple_entry&lt;1&gt;不一样,每个不同的实例化返回元组的不同元素。

    这真的和

    没有什么不同
    #include <iostream>
    
    template<int N>
    void func()
    {
        std::cout << N << '\n';
    }
    
    int main()
    {
        func<0>();
        func<1>();
        func<2>();
    }
    

    这调用了三个不同的函数来打印不同的东西,但是相同的签名没有问题,因为func&lt;0&gt;()func&lt;1&gt;()func&lt;2&gt;()都是不同的函数。如果您查看损坏的名称,您会发现它们具有不同的签名,例如使用 G++,我得到 _Z4funcILi0EEvv_Z4funcILi1EEvv_Z4funcILi2EEvv,它们不是同一个签名。

    【讨论】:

    • 谢谢。特别是对于您的简单示例。这真的让我大开眼界。
    猜你喜欢
    • 2013-09-14
    • 1970-01-01
    • 2012-10-26
    • 2014-02-01
    • 2020-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-09
    相关资源
    最近更新 更多