C ++模板臭名昭著,因为它会生成冗长且无法读取的错误消息。我对C ++中的模板错误消息为何如此糟糕有一个大致的了解。本质上,问题在于直到编译器遇到模板中某种类型不支持的语法时才触发错误。例如:
template <class T>
void dosomething(T& x) { x += 5; }
如果T
不支持该+=
运算符,则编译器将生成一条错误消息。而且,如果这种情况发生在某处库的深处,则错误消息可能长达数千行。
但是C ++模板本质上只是一种编译时鸭子类型的机制。C ++模板错误从概念上讲非常类似于动态语言(例如Python)中可能发生的运行时类型错误。例如,考虑以下Python代码:
def dosomething(x):
x.foo()
在这里,如果x
没有foo()
方法,Python解释器将引发异常,并显示堆栈跟踪以及非常清楚的错误消息,指出问题所在。即使直到解释器深入某个库函数内部才触发错误,运行时错误消息也仍然不像典型的C ++编译器所发出的不可读呕吐那样糟糕。那么,为什么C ++编译器无法更清楚地指出出了什么问题?为什么某些C ++模板错误消息从字面上导致我的控制台窗口滚动5秒钟以上?
clang++
眨眼眨眼)。