GCC的两个异常错误信息

发布于 2024-10-21 13:16:57 字数 1702 浏览 1 评论 0原文

今天,我遇到了两条以前从未见过的错误消息。这对我来说是全新的。

代码如下:

template<typename T>
struct adder { adder(const T &item) { } };

template<typename T>
void initializer(const T &item) {  adder<T>(item); }

int main() 
{
   initializer("const string literal");
}

编译时,GCC 给出以下错误:

prog.cpp:在函数“voidinitializer(const T&)”中:
prog.cpp:6: 错误:'adder的声明item' 隐藏参数
prog.cpp:在函数“voidinitializer(const T&) [with T = char [21]]”中:
prog.cpp:10:从这里实例化
prog.cpp:6: 错误:'adder的声明item' 隐藏参数
prog.cpp:6: 错误:没有匹配的函数可用于调用 'adder::adder()'
prog.cpp:3:注意:候选者为:adder::adder(const T&) [with T = char [21]]
prog.cpp:3: 注意:adder::adder(const adder&)


请参阅粗体文本。一个错误显示两次,就是这个

错误:声明“adder” item' 隐藏参数
错误:声明 'adder; item' 隐藏参数

是什么意思?为什么它使用不同的模板参数显示两次?第一个带有 T,第二个带有 char [21]

编辑:adder(item) 是否声明名为 item 的变量?但这不是我的本意。我认为它应该创建一个临时对象,将 item 作为参数传递给构造函数。

我想知道标准中处理此问题的部分!


其他有趣的错误是:

错误:没有匹配的函数可用于调用“adder::adder()”

这表明编译器正在寻找默认构造函数?但我想知道为什么编译器要寻找它,而事实上我的代码在第 6 行并没有使用它?


ideone 上的代码: http://www.ideone.com/jrdLL

Today, I came across two error messages which I never seen before. It's completely new to me.

Here is the code:

template<typename T>
struct adder { adder(const T &item) { } };

template<typename T>
void initializer(const T &item) {  adder<T>(item); }

int main() 
{
   initializer("const string literal");
}

On compiling, GCC gives these errors:

prog.cpp: In function ‘void initializer(const T&)’:
prog.cpp:6: error: declaration of ‘adder<T> item’ shadows a parameter
prog.cpp: In function ‘void initializer(const T&) [with T = char [21]]’:
prog.cpp:10: instantiated from here
prog.cpp:6: error: declaration of ‘adder<char [21]> item’ shadows a parameter
prog.cpp:6: error: no matching function for call to ‘adder<char [21]>::adder()’
prog.cpp:3: note: candidates are: adder<T>::adder(const T&) [with T = char [21]]
prog.cpp:3: note: adder<char [21]>::adder(const adder<char [21]>&)


See the bold text. One error is shown twice, which is this

error: declaration of ‘adder<T> item’ shadows a parameter
error: declaration of ‘adder<char [21]> item’ shadows a parameter

What does it mean? Why does it show twice with different template arguments? First one with T, second one with char [21]?

EDIT: does adder<T>(item) declare variable with name item? But that is not what I intended. I think it should create a temporary object passing item as argument to the constructor.

I would like to know the section from the Standard which deals with this issue!


Other interesting error is this:

error: no matching function for call to ‘adder<char [21]>::adder()’

Which indicates that the compiler is looking for default constructor? But I'm wondering why is the compiler looking for it when in fact my code doesn't use it at line 6?


Code at ideone : http://www.ideone.com/jrdLL

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

眼眸里的快感 2024-10-28 13:17:03

理解正在发生的事情的关键是要认识到:
加法器(项目);
是一个名为 item 且具有类型的局部变量的定义
加法器;括号是多余的,但完美
允许的。如果你想调用构造函数,你将有
通过以某种不可能的方式书写来消除歧义
解释为数据定义,例如:
加法器((项目));
(我不确定这有什么用。它构造了一个临时的
adder 的对象,然后在末尾销毁它
表达式。)

一旦语句出现,实际的错误消息应该是清楚的(呃)
可以理解为数据声明:函数参数是
视为它们是在顶级块中定义的
函数,所以 adder(item) 是重复的(并且矛盾的)
定义,并且 adder 没有默认构造函数,所以
如果不提供参数就无法定义它的实例。

The key to understanding what is happening is to realize that:
adder(item);
is a definition of a local variable named item and having type
adder; the parentheses are superfluous, but perfectly
permissable. If you want to call the constructor, you'll have
to disambiguate, by writing it in some way that cannot be
interpreted as a data definition, say:
adder((item));
(I'm not sure what use this may be. It constructs a temporary
object of adder, then destructs it at the end of the
expression.)

The actual error messages should be clear(er) once the statement
is understood as a data declaration: function parameters are
treated as if they were defined in the top level block of the
function, so adder(item) is a duplicate (and contradictory)
definition, and adder doesn't have a default constructor, so
you can't define an instance of it without providing arguments.

野心澎湃 2024-10-28 13:17:03

我目前只能访问 C++0x 草案,因此我无法向您提供当前的章节和诗句,但我认为没有太大变化。
在 0x 中,它位于第 6.8 节 - 歧义解决:

语法中有歧义
涉及表达式语句和
声明:表达式语句
具有函数风格的显式类型
转换(5.2.3)为其最左边
子表达式可能无法区分
来自第一个声明
声明符以 ( 开头。在那些
在这种情况下,该声明是一个声明。

[...]

T(a); // declaration

也就是说,一个名为“a”、类型为 T 的变量的声明。

如果您的 adder(item) 要定义一个临时(未命名)对象,那么它将是一个表达式语句,但如果某些内容可以被解析为声明语句或表达式语句,则 C++ 会将其解析为声明语句。

[...]该决议是考虑任何
构造可能是
声明声明。
(8.2)

换句话说,它是每个人亲爱的老朋友“最令人烦恼的解析”的表弟。

更新:
我查看了 C++03 中的歧义解决,这些段落是相同的。

I only have access to the C++0x draft at the moment, so I can't give you the current chapter and verse, but I don't think much has changed.
In 0x it's in section 6.8 - Ambiguity Resolution:

There is an ambiguity in the grammar
involving expression-statements and
declarations: An expression-statement
with a function-style explicit type
conversion (5.2.3) as its leftmost
subexpression can be indistinguishable
from a declaration where the first
declarator starts with a (. In those
cases the statement is a declaration.

[...]

T(a); // declaration

That is, a declaration of a variable named "a" of type T.

If your adder<T>(item) were to define a temporary (un-named) object, it would be an expression-statement, but if something can be parsed as either a declaration-statement or an expression-statement, C++ parses it as a declaration-statement.

[...] the resolution is to consider any
construct that could possibly be a
declaration a declaration.
(8.2)

In other words, it's a cousin to everyone's dear old friend, the Most Vexing Parse.

Update:
I looked at ambiguity resolution in C++03, and those passages are identical.

花伊自在美 2024-10-28 13:17:03

“遮蔽”意味着两个对象具有相同的名称,语言目前允许这样做,但可能不是有意的。

"shadowing" means that two objects have the same name, which the language allows at this point, but might not be intended.

病毒体 2024-10-28 13:17:02

这表明编译器正在寻找默认构造函数?但我想知道为什么编译器要寻找它,而事实上我的代码在第 6 行并没有使用它?

因为编译器认为您用名称 item 声明了局部变量。

http://codepad.org/YBPKCvmm

Which indicates that the compiler is looking for default constructor? But I'm wondering why is the compiler looking for it when in fact my code doesn't use it at line 6?

Because compiler think that you declare local variable with name item.

http://codepad.org/YBPKCvmm

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文