转发可变参数列表

Forwarding variadic list of arguments

以下两个代码都按预期编译和执行,它们有什么不同吗?

template<typename T, typename ...U>
auto time_function(T&& func, U&& ...args)
{
   std::cout << "timing" << std::endl;
   auto val = std::forward<T>(func)(std::forward<U...>(args...));
   std::cout << "timing over" << std::endl;
   return val;
}

template<typename T, typename ...U>
auto time_function(T&& func, U&& ...args)
{
   std::cout << "timing" << std::endl;
   auto val = std::forward<T>(func)(std::forward<U>(args)...);
   std::cout << "timing over" << std::endl;
   return val;
}

查看 SO How would one call std::forward on all arguments in a variadic function?,第二个似乎是推荐的,但是第一个不是做同样的事情吗?

它们不一样。在args的元数为1或0的情况下它们是相同的。否则会编译失败,考虑..

#include <iostream>
using namespace std;
template<typename T, typename ...U>
auto time_function_1(T&& func, U&& ...args)
{

    std::cout<<"timing"<<std::endl;
    auto val = std::forward<T>(func)(std::forward<U...>(args...));
    std::cout<<"timing over"<<std::endl;
    return val;
}

    template<typename T, typename ...U>
auto time_function_2(T&& func, U&& ...args)
{

    std::cout<<"timing"<<std::endl;
    auto val = std::forward<T>(func)(std::forward<U>(args)...);
    std::cout<<"timing over"<<std::endl;
    return val;
}



int f (int){return 0;}

int y (int,int){return 0;}

int main() {
    time_function_1(f,1);
    time_function_2(f,1);

    time_function_1(y,1,2); // fail
    time_function_2(y,1,2);
    return 0;
}

Demo

对于失败案例 std::forward<U...>(args...) 扩展为 forward<int, int>(int&, int&) 并且将无法编译。

std::forward<U>(args)... 扩展为 std::forward<int>(int&),std::forward<int>(int&)