1

我只花了几个小时调试一个编译器错误,如果编译器的错误消息更有帮助,我可以立即修复它。

我把它简化为一个简单的例子:

template <typename T>
int f(int);

template <typename U>
auto g(U x) -> decltype(f(x));

int main()
{
    g(0);
}

错误是:

test.cpp: In function 'int main()':
test.cpp:9:8: error: no matching function for call to 'g(int)'
test.cpp:9:8: note: candidate is:
test.cpp:5:29: note: template<class U> decltype (f(x)) g(U)

这个错误在最好的情况下不是误导,在最坏的情况下是完全错误的吗?在我看来,问题在于给定的 g 定义与调用不匹配,而是该定义格式错误(因为在 decltype 中的表达式 f(x) 中,它尝试调用 f 而不指定f 的模板参数)。

一个更合理的错误消息不会是这样的:

no matching function for call to 'f(int)' in 'decltype(f(x))'
in instantiation of 'g(U)' with U = int

甚至更好:

failed to deduce template parameter 1 in call to 'f(int)' in 'decltype(f(x))'
in instantiation of 'g(U)' with U = int

我会期待这样的事情......

4

2 回答 2

1

您很可能在 C++0x 中遇到了“扩展 SFINAE”规则;由于对的调用f(x)在返回类型的实例化中不起作用g(因为无法推断T对调用的调用f),g因此返回类型无效,因此会默默地从重载集中删除。这是一个特性,尽管它会损害错误消息的质量,因为编译器假设这g是一个您不打算调用的不相关函数。在这种情况下,没有其他重载g,因此编译器应该给出更好的消息。

有关扩展 SFINAE 的更多信息,请访问http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2634.html

于 2011-01-23T03:58:20.667 回答
1

使用 Clang 我收到此错误

C:\Users\SUPER USER\Desktop>clang++ -cc1 -std=c++0x aa.cpp
aa.cpp:9:5: error: no matching function for call to 'g'
    g(0);
    ^
aa.cpp:5:6: note: candidate template ignored: substitution failure [with U = int
]
auto g(U x) -> decltype(f(x)){}
     ^
1 error generated.

比 g++ 产生的错误更容易理解

于 2011-01-23T05:55:10.610 回答