扩展参数包的默认函数参数 "fill in" 可以吗?
Can default function arguments "fill in" for expanded parameter packs?
下面的代码fails to compile:
#include <iostream>
template<typename F, typename ...Args>
static auto wrap(F func, Args&&... args)
{
return func(std::forward<Args>(args)...);
}
void f1(int, char, double)
{
std::cout << "do nada1\n";
}
void f2(int, char='a', double=0.)
{
std::cout << "do nada2\n";
}
int main()
{
wrap(f1, 1, 'a', 2.);
wrap(f2, 1, 'a');
}
g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp: In instantiation of 'auto wrap(F, Args&& ...) [with F = void(*)(int, char, double); Args = {int, char}]':
main.cpp:22:20: required from here
main.cpp:6:44: error: too few arguments to function
return func(std::forward<Args>(args)...);
似乎遵循了关于 "parameter packs being last" 的规则(至少在声明中是这样)并且在扩展之后应该形成正确的函数调用:f2
可以用 1、2 调用或 3 个参数,因此 too few arguments
似乎是一个错误 'harsh'。它看起来也不像 deduction problem(这是我的猜测 - 但由于错误消息而变得不稳定)
这是缺失的功能还是违反了标准?
您没有使用模板中的默认参数调用函数。
您正在调用一个函数指针,它指向一个函数,该函数正好需要 3 个参数,不多也不少。
编译器当然会抱怨缺少第三个。
你可以用可变仿函数做你想做的事,since C++14 even a lambda:
wrap([](auto&&... args){return f2(std::forward<decltype(args)>(args)...);}, 1, 'a');
下面的代码fails to compile:
#include <iostream>
template<typename F, typename ...Args>
static auto wrap(F func, Args&&... args)
{
return func(std::forward<Args>(args)...);
}
void f1(int, char, double)
{
std::cout << "do nada1\n";
}
void f2(int, char='a', double=0.)
{
std::cout << "do nada2\n";
}
int main()
{
wrap(f1, 1, 'a', 2.);
wrap(f2, 1, 'a');
}
g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp: In instantiation of 'auto wrap(F, Args&& ...) [with F = void(*)(int, char, double); Args = {int, char}]':
main.cpp:22:20: required from here
main.cpp:6:44: error: too few arguments to function
return func(std::forward<Args>(args)...);
似乎遵循了关于 "parameter packs being last" 的规则(至少在声明中是这样)并且在扩展之后应该形成正确的函数调用:f2
可以用 1、2 调用或 3 个参数,因此 too few arguments
似乎是一个错误 'harsh'。它看起来也不像 deduction problem(这是我的猜测 - 但由于错误消息而变得不稳定)
这是缺失的功能还是违反了标准?
您没有使用模板中的默认参数调用函数。
您正在调用一个函数指针,它指向一个函数,该函数正好需要 3 个参数,不多也不少。
编译器当然会抱怨缺少第三个。
你可以用可变仿函数做你想做的事,since C++14 even a lambda:
wrap([](auto&&... args){return f2(std::forward<decltype(args)>(args)...);}, 1, 'a');