在函数调用中临时的构造被解释为声明 [英] Construction of temporary in function call is interpreted as declaration
问题描述
最近我碰到一个问题,不知何故(但只是在某种程度上)对我有意义。它基于将临时构造解释为单个(!)构造函数参数的声明。请查看下面的最小示例。
#include< iostream&
class Foo0 {
public:
Foo0(int a){};
void doStuff(){std :: cout<<maap<< std :: endl;};
};
class Foo1 {
public:
Foo1(int a){};
void doStuff(){std :: cout<<maap<< std :: endl;};
};
class Foo2 {
public:
Foo2(int a){};
void doStuff(){std :: cout<<maap<< std :: endl;};
};
class Bar {
public:
Bar(Foo0 foo0,Foo1 foo1,Foo2 foo2){};
};
int main(){
int x = 1;
bar bar0(Foo0(x),Foo1(x),Foo2(x)); //不工作:冲突声明'Foo1 x'上一个声明为'Foo0 x';冲突声明'Foo2 x'上一个声明为'Foo0 x'
条形bar1(Foo0 {x},Foo1(x),Foo2(x)); // Works WTF
Bar bar2(Foo0(x),Foo1 {x},Foo2(x)); // Works WTF
bar bar3(Foo0(x),Foo1(x),Foo2 {x}); //不工作:冲突声明'Foo1 x'上一个声明为'Foo0 x'
bar bar4(Foo0 {x},Foo1 {x},Foo2 {x}); //工作完全使感觉到我
x.doStuff(); //剂量不工作。这使我感觉到。但在上下文中的好奇虽然。
}
我已经读过以下表达式:
Foo(a);
被解释(如果有一个标准构造函数)这是有道理的,它是完全正常的,因为你可以使用{} - 框架使结构明确。但我不明白的是:
-
为什么bar0的构造有问题?
/ li>
所有Foo
s没有标准构造函数。所以将Foo0(x)
解释为x
的声明没有意义。
-
为什么
bar1
和bar2
对我来说很明显,bar4
的构造工作,因为我使用{} - brackets所有临时Foo $
-
如果只需要使用{} - brackets只有一个
Foo
以解决问题...为什么bar3
的构造失败? -
此外,x在任何Bar构造之前声明。为什么编译器不会抱怨呢?
最后一个问题与我的最后一行示例代码有关。长篇小说:编译器认为我希望他做什么,我在哪里错过阴影的出现?
PS:如果感兴趣 - 我使用gcc-4.9.2。
PPS:我试着用 bar
的构造函数取三个 Foo0
s作为参数。同样的故事在这里。但是错误没有说明冲突声明,而是关于
x
的重新定义。
规则是,如果一个声明具有一个函数声明的语法,那么它是一个;否则是一个变量声明。令人惊讶的例子有时被称为的问题bar x0(Foo0(x),Foo1(x),Foo2(x))。 )); //不工作:冲突声明'Foo1 x'上一个声明为'Foo0 x';冲突声明'Foo2 x'上一个声明为'Foo0 x' 这是一个函数声明: 这些行和创建对象 因此, 这是一个编译器错误;部分 Lately I ran into a problem which somehow (but only somehow) makes sense to me. It is based on interpreting the construction of a temporary as declaration of the single (!) constructor argument. Please have a look at the minimal example below. I already read that expressions like: Are interpreted (if there is a standard constructor) as declaration of a. This makes sense and it is totally fine, since you can just use the {}-brackets to make the construction explicit. But what I do not understand is: Why is there a problem with the construction of bar0?
All Why does the construction of If it is only necessary to use the {}-brackets with only one of the Furthermore, x is declared before any Bar is constructed. Why does the compiler not complain about that? The last question is related to my last line of example code. Long story short: What does the compiler think that I want him to do and where do I miss the appearance of shadowing? PS: If it is of interest -- I use the gcc-4.9.2. The rule is that if a declaration has the syntax of a function declaration then it is one; otherwise it is a variable declaration. Surprising instances of this are sometimes called most-vexing-parse. This is a function declaration: These lines and create objects Therefore, I think this is a compiler bug; the part 这篇关于在函数调用中临时的构造被解释为声明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
bar0
是名称, Bar
是返回类型,参数类型为 Foo0
, Foo1
和 Foo2
。参数名都是 x
,这是非法的 - 函数参数的名称必须不同。如果您更改 x
x
x
至 x
y
z
错误消失)。
$ b
条形bar1(Foo0 {x},Foo1(x),Foo2(x)); // Works WTF
Bar bar2(Foo0(x),Foo1 {x},Foo2(x)); // Works WTF
bar bar4(Foo0 {x},Foo1 {x},Foo2 {x}); //工作完全使我感觉到
bar1
, bar2
和 bar4
$ c>。它们不能被解析为函数声明,因为 {}
符号在函数声明中不是有效的语法。
Foo0 {x}
等是提供 Bar
的构造函数。 Foo0 {x}
和 Foo0(x)
是声明临时类型 Foo0 与初始设定器
x
。 bar3(Foo0(x),Foo1(x),Foo2 {x}); //不工作:冲突声明'Foo1 x'上一个声明为'Foo0 x'
Foo2 {x}
表示此行不能是函数声明;它看起来像一个变量 bar3
的有效声明。
x 。做东西(); //剂量不能工作。这使我感觉到。但在上下文中,好奇的
x
int
;它没有任何方法。#include <iostream>
class Foo0{
public:
Foo0(int a){};
void doStuff() {std::cout<<"maap"<<std::endl;};
};
class Foo1{
public:
Foo1(int a){};
void doStuff() {std::cout<<"maap"<<std::endl;};
};
class Foo2{
public:
Foo2(int a){};
void doStuff() {std::cout<<"maap"<<std::endl;};
};
class Bar{
public:
Bar(Foo0 foo0, Foo1 foo1, Foo2 foo2){};
};
int main () {
int x = 1;
Bar bar0(Foo0(x), Foo1(x), Foo2(x)); // Does not work: conflicting declaration ‘Foo1 x’ previous declaration as ‘Foo0 x’; conflicting declaration ‘Foo2 x’ previous declaration as ‘Foo0 x’
Bar bar1(Foo0{x}, Foo1(x), Foo2(x)); // Works WTF
Bar bar2(Foo0(x), Foo1{x}, Foo2(x)); // Works WTF
Bar bar3(Foo0(x), Foo1(x), Foo2{x}); // Does not work: conflicting declaration ‘Foo1 x’ previous declaration as ‘Foo0 x’
Bar bar4(Foo0{x}, Foo1{x}, Foo2{x}); // Works totally makes sens to me
x.doStuff(); //Dose not work. This makes sens to me. But in the context its curious though.
}
Foo(a);
Foo
s do not have a standard constructor. So it does not make sense to interpret something like Foo0(x)
as declaration of x
.bar1
and bar2
work?
It is obvious to me that the construction of bar4
works, since I use the {}-brackets for all temporary Foo
s, thus I am explicit about what I want.Foo
s to solve the problem... why does the construction of bar3
fail?
PPS: I tried the same with bar
's constructor taking three Foo0
s as arguments. Same story here. But the error says nothing about conflicting declaration but about redefinition of x
.Bar bar0(Foo0(x), Foo1(x), Foo2(x)); // Does not work: conflicting declaration ‘Foo1 x’ previous declaration as ‘Foo0 x’; conflicting declaration ‘Foo2 x’ previous declaration as ‘Foo0 x’
bar0
is the name, Bar
is the return type, and the parameter types are Foo0
, Foo1
and Foo2
. The parameter names are all x
which is illegal - the names of function parameters must be different. If you change x
x
x
to x
y
z
the error goes away).Bar bar1(Foo0{x}, Foo1(x), Foo2(x)); // Works WTF
Bar bar2(Foo0(x), Foo1{x}, Foo2(x)); // Works WTF
Bar bar4(Foo0{x}, Foo1{x}, Foo2{x}); // Works totally makes sens to me
bar1
, bar2
, and bar4
of type Bar
. They cannot be parsed as function declarations because the { }
notation is not valid syntax in a function declaration. Foo0{x}
etc. are expressions which provide the arguments to Bar
's constructor. Foo0{x}
and Foo0(x)
are equivalent ways of declaring a temporary of type Foo0
with initializer x
.Bar bar3(Foo0(x), Foo1(x), Foo2{x}); // Does not work: conflicting declaration ‘Foo1 x’ previous declaration as ‘Foo0 x’
Foo2{x}
means that this line cannot be a function declaration; and it looks like a valid declaration of a variable bar3
.x.doStuff(); //Dose not work. This makes sens to me. But in the context its curious
x
is an int
; it does not have any methods.