Пересылка переменного списка аргументов - PullRequest
3 голосов
/ 01 ноября 2019

Оба следующих кода компилируются и выполняются, как и ожидалось, отличаются ли они?

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 Как можно было бы вызвать std :: forward для всех аргументов в функции с переменными числами? , второе, кажется, рекомендуется, но разве первое не делает то же самое?

1 Ответ

3 голосов
/ 01 ноября 2019

Они не одинаковы. Они одинаковы в том случае, если арность 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;
}

Демо

для случая с ошибкой std::forward<U...>(args...) расширяется до forward<int, int>(int&, int&) и не может быть скомпилирован.

std::forward<U>(args)... расширяется до std::forward<int>(int&),std::forward<int>(int&)

...