问题 扩展参数包的默认函数参数可以“填写”吗?


以下代码 无法编译 :

#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)...);

似乎遵循关于“参数包最后”的规则(至少在声明中)并且在扩展之后应该形成正确的函数调用: f2 可以用1,2或3个参数调用,所以 too few arguments 是一个错误似乎'严厉'。它也看起来不像 扣除问题 (这是我的猜测 - 但由于错误信息而变得不稳定)

这是一个缺失的功能还是违反了标准的观点?


1559
2018-01-28 16:28


起源

它与clang 3.5引发了类似的错误 - OmnipotentEntity
VS2013给出这个:main.cpp(7):错误C3551:期望一个尾随返回类型 - abcthomas


答案:


您没有使用模板中的default-arguments调用函数。

你正在调用一个函数指针,它指向一个期望正好3个参数的函数,既不多也不少。

当然编译器对于丢失的第三个问题抱怨不已。

您可以使用可变参数函数执行您尝试执行的操作, 因为C ++ 14甚至是lambda

wrap([](auto&&... args){return f2(std::forward<decltype(args)>(args)...);}, 1, 'a'); 

10
2018-01-28 16:34



return f2(std::forward<decltype(args)>(args)...); - T.C.
..现在 * 在 void(*)(int, char, double) 突然写着一个 26喜欢 - Nikos Athanasiou