可变参数模板函数:每个参数的参数编号

时间:2014-06-17 15:42:59

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

我在C ++ 11中使用可变参数函数模板,并且使用类似的代码获得了基本的想法:

void helper()
{
    std::cout << "No args" << std::endl;
}

template< typename T >
void helper( T&& arg )
{
    size_t n = 0;
    std::cout << "arg " << n << " = " << arg << std::endl;
    helper();
}

template< typename T, typename... Arguments >
void helper( T&& arg, Arguments&& ... args )
{
    size_t n = sizeof...( args );
    std::cout << "arg " << n << " = " << arg << std::endl;
    helper( args... );
}

但是,我想要的是参数号(代码中的变量n)要向上计数而不是向下计数。我怎么能优雅地做到这一点?我可以写一个包装函数来创建一个隐藏的&#39;参数计数,但我觉得应该有一个更简洁的方式?

谢谢!

2 个答案:

答案 0 :(得分:2)

你是说这样的意思吗?我我明白你在寻找什么,但如果没有,我会毫不犹豫地放弃这个答案:

#include <iostream>
#include <utility>

void helper()
{
    std::cout << "no args" << std::endl;
}

template<size_t N, typename T>
void helper(T&& arg)
{
    std::cout << "arg " << N << " = " << arg << std::endl;
}

template<size_t N, typename T, typename... Args>
void helper(T&& arg, Args&&... args)
{
    helper<N>(std::forward<T>(arg));
    helper<N+1, Args...>(std::forward<Args>(args)...);
}

template<typename T, typename... Args>
void helper(T&& arg, Args&& ... args)
{
    helper<0>(std::forward<T>(arg), std::forward<Args>(args)... );
}

int main()
{
    helper();
    std::cout << '\n';

    helper("single");
    std::cout << '\n';

    helper("one", 2U);
    std::cout << '\n';

    helper(1,"two", 3.0, 4L);
    std::cout << '\n';

    return 0;
}

<强>输出

no args

arg 0 = single

arg 0 = one
arg 1 = 2

arg 0 = 1
arg 1 = two
arg 2 = 3
arg 3 = 4

See it live

答案 1 :(得分:0)

您可以执行以下操作:live example

#if 1 // Not in C++11 // make_index_sequence
#include <cstdint>

template <std::size_t...> struct index_sequence {};

template <std::size_t N, std::size_t... Is>
struct make_index_sequence : make_index_sequence<N - 1, N - 1, Is...> {};

template <std::size_t... Is>
struct make_index_sequence<0u, Is...> : index_sequence<Is...> {};

#endif // make_index_sequence


namespace detail
{
    template<std::size_t...Is, typename... Ts>
    void helper(index_sequence<Is...>, Ts&&...args)
    {
        int dummy[] = {0, ((std::cout << "arg " << Is << " = " << args << std::endl), 0)...};
        static_cast<void>(dummy);
    }

}

void helper()
{
    std::cout << "No args" << std::endl;
}

template<typename ... Ts>
void helper(Ts&&... args)
{
    detail::helper(make_index_sequence<sizeof...(Ts)>(), std::forward<Ts>(args)...);
}