I just spent a couple of hours debugging a compiler error that I could have fixed 开发者_StackOverflowimmediately if the compiler's error message had been more helpful.
I've reduced it to a simple example:
template <typename T>
int f(int);
template <typename U>
auto g(U x) -> decltype(f(x));
int main()
{
g(0);
}
The error is:
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)
Is this error not at best misleading and at worst, outright wrong? The way I see it, the problem is not that the given definition of g is not a match for the call, but that the definition is malformed (since in the expression f(x) in the decltype, it tries to call f without specifying f's template parameter).
Wouldn't a much more reasonable error message be something like:
no matching function for call to 'f(int)' in 'decltype(f(x))'
in instantiation of 'g(U)' with U = int
or even better:
failed to deduce template parameter 1 in call to 'f(int)' in 'decltype(f(x))'
in instantiation of 'g(U)' with U = int
I would have expected something like that...
You are most likely hitting the "extended SFINAE" rules in C++0x; since the call to f(x)
is not working within the instantiation of the return type of g
(because of the inability to deduce T
for the call to f
), g
has an invalid return type and thus is removed from the overload set silently. This is a feature, despite its harm to error message quality, because the compiler is assuming that g
is an unrelated function that you aren't intending to call. In this case, there are no other overloads of g
, so the compiler should give a better message, though.
There is more information on extended SFINAE available at http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2634.html.
With Clang I get this error
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.
Much easier to understand than the error produced by g++
精彩评论