在函数调用中临时的构造被解释为声明 [英] Construction of temporary in function call is interpreted as declaration

查看:218
本文介绍了在函数调用中临时的构造被解释为声明的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近我碰到一个问题,不知何故(但只是在某种程度上)对我有意义。它基于将临时构造解释为单个(!)构造函数参数的声明。请查看下面的最小示例。

  #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); 

被解释(如果有一个标准构造函数)这是有道理的,它是完全正常的,因为你可以使用{} - 框架使结构明确。但我不明白的是:


  1. 为什么bar0的构造有问题?
    所有 Foo s没有标准构造函数。所以将 Foo0(x)解释为 x 的声明没有意义。

    / li>
  2. 为什么 bar1 bar2
    对我来说很明显, bar4 的构造工作,因为我使用{} - brackets所有临时 Foo


  3. 如果只需要使用{} - brackets只有一个 Foo 以解决问题...为什么 bar3 的构造失败?


  4. 此外,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'

这是一个函数声明: 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 ;它没有任何方法。


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.

#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.
}

I already read that expressions like:

Foo(a);

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:

  1. Why is there a problem with the construction of bar0? All Foos do not have a standard constructor. So it does not make sense to interpret something like Foo0(x) as declaration of x.

  2. Why does the construction of bar1 and bar2 work? It is obvious to me that the construction of bar4 works, since I use the {}-brackets for all temporary Foos, thus I am explicit about what I want.

  3. If it is only necessary to use the {}-brackets with only one of the Foos to solve the problem... why does the construction of bar3 fail?

  4. 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.
PPS: I tried the same with bar's constructor taking three Foo0s as arguments. Same story here. But the error says nothing about conflicting declaration but about redefinition of x.

解决方案

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 .

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’

This is a function declaration: 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

These lines and create objects 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.

Therefore, 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’

I think this is a compiler bug; the part 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.

这篇关于在函数调用中临时的构造被解释为声明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆