Можно ли применить переменную функцию к кортежу с помощью 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>
?
С 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);
Других решений пока нет …