2011-01-23 65 views
1

我刚刚花了几个小时调试编译器错误,如果编译器的错误消息更有帮助,我可以立即修复这个错误。无益(可能是错误的?)gcc错误消息

我它减少到一个简单的例子:

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 

我本来期望类似的东西...

+0

哪个GCC的版本在哪个平台产生的误差?这是一个G ++扩展还是新的C++ 0x语法?鉴于使用`auto`,我认为后者。 – 2011-01-23 03:59:56

+0

@Jonathan:decltype和后期指定的返回类型是C++ 0x(因此这个问题的C++ 0x标签)的新增内容。自(至少)版本4.4以来,它们一直由gcc支持。我引用的错误是由gcc 4.6的实验版本产生的,但4.4和4.5给出了类似的错误。 – HighCommander4 2011-01-23 04:04:28

回答

1

你最有可能在C++ 0x中触发“扩展的SFINAE”规则;由于f(x)的呼叫在返回类型g的实例化中不起作用(因为无法对f的呼叫推导出T),因此g具有无效的返回类型,因此将以无提示的方式从超载集中移除。尽管它对错误消息质量有害,但这是一个功能,因为编译器假定g是一个不相关的函数,您不打算调用它。在这种情况下,g没有其他重载,所以编译器应该给出更好的消息。

有更多关于扩展SFINAE的信息可在http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2634.html

1

铿锵我得到这个错误

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 ++