void f(const int& i){}
int main(void)
{
int i = 1;
f(i);
f(2);
const int&r1 = i;
const int&r2 = 2;
return 0;
}
这都没有问题,那么为什么下面的代码(来自另一个帖子)
class X
{
public:
X(int i){ cout << __FUNCTION__ << endl; }
X(){ cout << __FUNCTION__ << endl; }
X(const X&){ cout << __FUNCTION__ << endl; }
X(X&&){ cout << __FUNCTION__ << endl; }
};
int main(void)
{
X x(X());
return 0;
}
main函数当中的X x(X())被编译器认为是一个函数声明,而不是一个x变量的实例呢? 如果const X&可以绑定X()这样的临时变量(右值),为什么不是用X的拷贝构造函数,构造了一个x?
之前有一位大侠指出如果写成X x((X())),就是调用了一个默认对象的构造。但是这也不是我期待的:这样改的效果,似乎是一个函数声明加一个默认构造,而没有我期待的拷贝构造。
我希望知道语法上的原因,为什么这里X x(X())是一个函数声明?
非常感谢。。。。。。。。
10 个解决方案
#1
X x(
X());
单独把X() 拿出来做一句话执行确实是构造了一个匿名X对象。
但是放在整句话中情况就不一样了, 编译器看到这句话的时候一定会将它看做一个函数声明, X()变成了函数形参
理由: 在编译阶段X()不会为你构建出一个X对象,不会为X() 构建出的对象在内存中开辟一块空间, 构建对象的过程是在程序执行过程中构建的, 既然X() 不是一个对象, 那么又怎么调用拷贝构造函数呢, 这就是静态语言
你希望看到拷贝构造,何不显式的写出来
X x1;
X x2 = x1; //调用拷贝构造函数
单独把X() 拿出来做一句话执行确实是构造了一个匿名X对象。
但是放在整句话中情况就不一样了, 编译器看到这句话的时候一定会将它看做一个函数声明, X()变成了函数形参
理由: 在编译阶段X()不会为你构建出一个X对象,不会为X() 构建出的对象在内存中开辟一块空间, 构建对象的过程是在程序执行过程中构建的, 既然X() 不是一个对象, 那么又怎么调用拷贝构造函数呢, 这就是静态语言
你希望看到拷贝构造,何不显式的写出来
X x1;
X x2 = x1; //调用拷贝构造函数
#2
我都看不明白第一份代码是在干啥·····哪个大哥能给我解释一下这个操作的目的是啥。
#3
most vexing parse。这是parse阶段的二义性,它既可以解释成函数声明也可以解释成对象声明,既然标准规定parse成前者,那你再认为后者怎么有道理也是没用的。
要达到你的目的你需要多写一组括号X x((X()));或者你既然在C++11了,可以用unified initialization:X x{X{}};
要达到你的目的你需要多写一组括号X x((X()));或者你既然在C++11了,可以用unified initialization:X x{X{}};
#4
X x(X())
怎么作为一个函数声明解析呢
x是函数名,他的参数是什么类型呢:X()显然不是一个类型
怎么作为一个函数声明解析呢
x是函数名,他的参数是什么类型呢:X()显然不是一个类型
#5
X x(X());
相当于
X x(X (*)());
#include <iostream>
using namespace std;
class X
{
};
X f1()
{
X x;
cout << __PRETTY_FUNCTION__ << endl;
return x;
}
X f2()
{
X x;
cout << __PRETTY_FUNCTION__ << endl;
return x;
}
int main(void)
{
X x(X());
x(f1);
x(f2);
return 0;
}
X x(X (*pf)())
{
cout << __PRETTY_FUNCTION__ << endl;
return pf();
}
#6
因为标准说了,凡是既能理解为声明,又能理解为定义的文字,都统一按声明处理。
#7
这个在标准里面的什么章节呢?
我手边的文档是ISO+IEC+14882-2011的c++标准。
#8
谢谢你的回复,那如何解释如果我把main函数改成了:
[code]
#include<vector>
#include<iostream>
using namespace std;
class X
{
public:
X(int i){ cout << __FUNCTION__ << endl; }
X(){ cout << "default ctor" << endl; }
X(const X&){ cout << "copy constructor" << endl; }
X(X&&){ cout << "move constructor" << endl; }
};
int main(void)
{
X x((X())); // 这里改变了,增加了一层括号。
return 0;
}[/code]
为什么打印出了一个default ctor,
(1) 如果还是一个声明,就不应该执行任何东西
(2) 如果是对象创建,那么是不是应该创建了两个对象,一个临时对象X(),一个用拷贝构造函数创建的x
是这样的吗?
#9
c++优先解释为函数
#10
c++11 8.2/1
#1
X x(
X());
单独把X() 拿出来做一句话执行确实是构造了一个匿名X对象。
但是放在整句话中情况就不一样了, 编译器看到这句话的时候一定会将它看做一个函数声明, X()变成了函数形参
理由: 在编译阶段X()不会为你构建出一个X对象,不会为X() 构建出的对象在内存中开辟一块空间, 构建对象的过程是在程序执行过程中构建的, 既然X() 不是一个对象, 那么又怎么调用拷贝构造函数呢, 这就是静态语言
你希望看到拷贝构造,何不显式的写出来
X x1;
X x2 = x1; //调用拷贝构造函数
单独把X() 拿出来做一句话执行确实是构造了一个匿名X对象。
但是放在整句话中情况就不一样了, 编译器看到这句话的时候一定会将它看做一个函数声明, X()变成了函数形参
理由: 在编译阶段X()不会为你构建出一个X对象,不会为X() 构建出的对象在内存中开辟一块空间, 构建对象的过程是在程序执行过程中构建的, 既然X() 不是一个对象, 那么又怎么调用拷贝构造函数呢, 这就是静态语言
你希望看到拷贝构造,何不显式的写出来
X x1;
X x2 = x1; //调用拷贝构造函数
#2
我都看不明白第一份代码是在干啥·····哪个大哥能给我解释一下这个操作的目的是啥。
#3
most vexing parse。这是parse阶段的二义性,它既可以解释成函数声明也可以解释成对象声明,既然标准规定parse成前者,那你再认为后者怎么有道理也是没用的。
要达到你的目的你需要多写一组括号X x((X()));或者你既然在C++11了,可以用unified initialization:X x{X{}};
要达到你的目的你需要多写一组括号X x((X()));或者你既然在C++11了,可以用unified initialization:X x{X{}};
#4
X x(X())
怎么作为一个函数声明解析呢
x是函数名,他的参数是什么类型呢:X()显然不是一个类型
怎么作为一个函数声明解析呢
x是函数名,他的参数是什么类型呢:X()显然不是一个类型
#5
X x(X())
怎么作为一个函数声明解析呢
x是函数名,他的参数是什么类型呢:X()显然不是一个类型
X x(X());
相当于
X x(X (*)());
#include <iostream>
using namespace std;
class X
{
};
X f1()
{
X x;
cout << __PRETTY_FUNCTION__ << endl;
return x;
}
X f2()
{
X x;
cout << __PRETTY_FUNCTION__ << endl;
return x;
}
int main(void)
{
X x(X());
x(f1);
x(f2);
return 0;
}
X x(X (*pf)())
{
cout << __PRETTY_FUNCTION__ << endl;
return pf();
}
#6
因为标准说了,凡是既能理解为声明,又能理解为定义的文字,都统一按声明处理。
#7
因为标准说了,凡是既能理解为声明,又能理解为定义的文字,都统一按声明处理。
这个在标准里面的什么章节呢?
我手边的文档是ISO+IEC+14882-2011的c++标准。
#8
谢谢你的回复,那如何解释如果我把main函数改成了:
[code]
#include<vector>
#include<iostream>
using namespace std;
class X
{
public:
X(int i){ cout << __FUNCTION__ << endl; }
X(){ cout << "default ctor" << endl; }
X(const X&){ cout << "copy constructor" << endl; }
X(X&&){ cout << "move constructor" << endl; }
};
int main(void)
{
X x((X())); // 这里改变了,增加了一层括号。
return 0;
}[/code]
为什么打印出了一个default ctor,
(1) 如果还是一个声明,就不应该执行任何东西
(2) 如果是对象创建,那么是不是应该创建了两个对象,一个临时对象X(),一个用拷贝构造函数创建的x
是这样的吗?
#9
c++优先解释为函数
#10
因为标准说了,凡是既能理解为声明,又能理解为定义的文字,都统一按声明处理。
这个在标准里面的什么章节呢?
我手边的文档是ISO+IEC+14882-2011的c++标准。
c++11 8.2/1