【问题标题】:Variadic function template strange error message for unresolved overloaded argument未解析的重载参数的可变参数函数模板奇怪的错误消息
【发布时间】:2016-05-01 03:30:39
【问题描述】:

我在不小心将重载函数传递给可变参数函数模板时遇到了一个令人困惑的错误:

template<typename... Args>
void variadic(Args... args) {}

void overloaded() {}
void overloaded(int) {}

int main()
{
    variadic(overloaded);
}

错误:

prog.cpp: In function 'int main()':
prog.cpp:9:24: error: too many arguments to function 'void variadic(Args ...) [with Args = {}]'
     variadic(overloaded);
                    ^
prog.cpp:2:6: note: declared here
 void variadic(Args... args) {}
      ^

如果我用普通函数模板替换可变参数函数模板,我会收到更清晰的错误消息:

prog.cpp: In function 'int main()':
prog.cpp:9:25: error: no matching function for call to 'templated(<unresolved overloaded function type>)'
     templated(overloaded);
                         ^
prog.cpp:2:6: note: candidate: template<class Arg> void templated(Arg)  void templated(Arg args) {}
      ^
prog.cpp:2:6: note:   template argument deduction/substitution failed:
prog.cpp:9:25: note:   couldn't deduce template parameter 'Arg'
     templated(overloaded);
                         ^

谁能解释为什么可变参数错误消息不同?我知道为什么会有一个,只是不知道为什么它与正常的模板错误不同。

我正在使用带有 C++14 的 g++ 5.2.1。

在这里试试:https://ideone.com/8XZexs

【问题讨论】:

  • 你的代码有歧义,编译器应该如何决定将哪个overloaded函数传递给variadic函数。
  • @t.niese 我知道是的。我只是想了解为什么这两个错误消息(可变参数与非可变参数)不同
  • Visual Studio 抱怨 error C2660: 'variadic': function does not take 1 arguments
  • clang 告诉你 Candidate function not viable: requires 0 arguments, but 1 was provided 的可变参数版本,我会假设因为它是模棱两可的,所以没有创建带有一个参数的 variadic 函数版本,因为你得到了传递错误参数计数的消息。对于模板版本,参数计数是固定的,因此对类型进行更具体的测试会失败。

标签: c++ variadic-templates


【解决方案1】:

最终,为什么错误消息的问题不是有趣的问题 - 没有标准可以管理错误消息包含的内容。重要的一点是 gcc(和 clang)正确地拒绝了格式错误的代码,并且能够指向有问题的行。

来自 gcc 的错误:

main.cpp:9:24: error: too many arguments to function 'void variadic(Args ...) [with Args = {}]'
     variadic(overloaded);
                    ^

和叮当声:

main.cpp:9:5: error: no matching function for call to 'variadic'
    variadic(overloaded);
    ^~~~~~~~
main.cpp:2:6: note: candidate function not viable: requires 0 arguments, but 1 was provided
void variadic(Args... args) {}
     ^

恰好具有误导性。似乎未能为overloaded 推断出Args...(因为无法推断),两个编译器都回退到尝试为Args... 实例化一个空参数包,并且只报告@987654326 的不可行性@ 作为variadic(overloaded) 的重载。在非可变情况下,没有这样的回退,两个编译器错误都更有用。

这是一个糟糕的错误消息,希望未来的一些编译器版本会改进它 - 但重要的是要了解 为什么 代码格式错误(如您所见),而不是具体的错误信息恰好是。

【讨论】:

  • 这个解释很有道理。谢谢
【解决方案2】:

您确定要将指向函数的指针传递给variadic 函数吗?

如果这确实是您想要做的,那么您需要明确指定要传递的函数的指针。例如(选择overloaded(int)):

void (*fn)(int) = overloaded;
variadic(fn);

或(选择overloaded()

void (*fn)() = overloaded;
variadic(fn);

【讨论】:

  • 对不起,但这并不能回答我的问题。我想知道为什么错误消息不同,而不是为什么它们存在。
猜你喜欢
  • 2015-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多