【问题标题】:Why function default parameters cannot be perferct forwarded in C++?为什么函数默认参数不能在 C++ 中完美转发?
【发布时间】:2017-07-12 22:06:00
【问题描述】:

从我的角度来看,我发现了非常奇怪的行为:函数默认参数无法在下面的代码中转发。

void Test(int test = int{}) {}

template<typename F, typename ...Args>
void Foo(F&& f, Args&&... args)
{
    std::forward<F>(f)(std::forward<Args>(args)...);
}

int main()
{
    Foo(Test, 0); // This compiles
    Foo(Test);    // This doesn't compile
}

Clang 报告: 错误:函数调用的参数太少,预期为 1,有 0 GCC 和 VC 报告相同的错误。

谁能解释一下?

代码在这里: http://rextester.com/live/JOCY22484

【问题讨论】:

  • 较短的测试用例:auto f = Test; f();

标签: c++ c++11 perfect-forwarding


【解决方案1】:

Test 是一个总是接受一个参数的函数。如果在按名称调用Test 时可以看到其带有默认参数的声明,则编译器将隐式地将默认参数添加到调用中。但是,一旦Test 被转换为指针或函数引用,默认参数信息将不再可见。

这可以通过创建一个函子来解决,该函子确实接受零个或一个参数,并将该信息编码到它的类型中,这样它就不会被破坏,如下所示:

struct Test {
    void operator()(int) { /* ... */ }
    void operator()() { operator(int{}); }
} test;
// ...
Foo(test, 0); // ok
Foo(test);    // ok

【讨论】:

  • void operator()(int = 0) { /* ... */ } 可以正常工作。
猜你喜欢
  • 2012-01-06
  • 2013-05-31
  • 1970-01-01
  • 1970-01-01
  • 2015-11-28
  • 2014-07-18
  • 2010-11-10
  • 2014-09-06
  • 1970-01-01
相关资源
最近更新 更多