Применение переменной функции с помощью std :: apply

Можно ли применить переменную функцию к кортежу с помощью std :: apply?

Например, следующий код прекрасно работает с GCC 6.2.1:

void print_t(std::string i, std::string j) {
std::cout << i << " " << j << std::endl;
}

int main() {
std::tuple<std::string, std::string> t{"ab", "cd"};
std::experimental::apply(print_t, t);
return 0;
}

Но если я попытаюсь применить переменную функцию:

template<typename T>
void vprint(T && t) {
std::cout << std::forward<T>(t) << std::endl;
}

template<typename T, typename ... Ts>
void vprint(T && t, Ts ... ts) {
std::cout << std::forward<T>(t) << " ";
vprint<Ts...>(std::forward<Ts>(ts)...);
}

int main() {
std::tuple<std::string, std::string> t{"fd", "ab"};
std::experimental::apply(vprint, t);
return 0;
}

компилятор жалуется, что не может вывести аргументы шаблона vprint, Хорошо, давайте напишем их явно:

std::experimental::apply(vprint<std::string, std::string>, t);

Теперь компилятор заканчивает некоторыми неясными ошибками, которые разоблачают внутреннюю часть стандартной библиотеки.

Я написал свою собственную реализацию std::apply в C ++ 11, и я понимаю, почему он не может вывести аргументы шаблона функции variadic. Но, теоретически, std::apply имеет всю информацию, необходимую для этого вычета.

Итак, является ли применение функций с переменным числом еще не реализованной функцией в GCC6? Позволят ли C ++ 17-совместимые компиляторы такое применение?
Если нет, то позволят ли они применять экземпляры шаблонных функций с переменными числами, такие как vprint<std::string, std::string>?

3

Решение

С vprint<std::string, std::string>, вы должны передать r-значение ссылки, так

std::experimental::apply(vprint<std::string, std::string>, std::move(t));

Лучше всего использовать функтор (благодаря универсальной лямбде):

std::experimental::apply([](auto&&... args) {
vprint(std::forward<decltype(args)>(args)...);
},
t);
6

Другие решения

Других решений пока нет …