我发现可以使用与下面示例中显示的名称相同的构造函数参数初始化成员变量.
#include <cstdio>
#include <vector>
class Blah {
std::vector<int> vec;
public:
Blah(std::vector<int> vec): vec(vec)
{}
void printVec() {
for(unsigned int i=0; i<vec.size(); i++)
printf("%i ", vec.at(i));
printf("\n");
}
};
int main() {
std::vector<int> myVector(3);
myVector.at(0) = 1;
myVector.at(1) = 2;
myVector.at(2) = 3;
Blah blah(myVector);
blah.printVec();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
带有参数的g ++ 4.4 -Wall -Wextra -pedantic没有提供任何警告并且工作正常.它也适用于clang ++.我想知道C++标准对此有何看法?是否合法并保证始终有效?
Naw*_*waz 83
我想知道C++标准对此有何看法?是否合法并保证始终有效?
是.这完全合法.完全符合标准.
Blah(std::vector<int> vec): vec(vec){}
^ ^
| |
| this is the argument to the constructor
this is your member data
Run Code Online (Sandbox Code Playgroud)
既然你在标准中要求参考,那么它就是一个例子.
§12.6.2/ 7
mem-initializer的表达式列表中的名称在为其指定mem-initializer的构造函数的范围内进行计算.
[Example:
class X {
int a;
int b;
int i;
int j;
public:
const int& r;
X(int i): r(a), b(i), i(i), j(this->i) {}
//^^^^ note this (added by Nawaz)
};
Run Code Online (Sandbox Code Playgroud)
初始化X :: r以引用X :: a,使用构造函数参数i的值初始化X :: b,使用构造函数参数i的值初始化X :: i,并使用值初始化X :: j X :: i; 每次创建类X的对象时都会发生这种情况.]
[注意:因为mem-initializer是在构造函数的范围内计算的,所以this指针可以在mem-initializer的表达式列表中用于引用正在初始化的对象.]
正如您所看到的,在上面的示例中还有其他有趣的事情需要注意,以及标准本身的注释.
BTW,作为旁注,为什么不接受参数作为const引用:
Blah(const std::vector<int> & vec): vec(vec) {}
^^^^const ^reference
Run Code Online (Sandbox Code Playgroud)
它避免了原始矢量对象的不必要副本.
Dav*_*eas 13
保证始终工作(我经常使用它).编译器知道初始化列表的形式为:member(value),因此它知道第一vec的vec(vec)必须是成员.现在,在初始化成员的参数上,可以使用构造函数的参数和其他符号,就像在构造函数中存在的任何表达式一样.此时它应用常规查找规则,并且参数vec隐藏该成员vec.
该标准的第12.6.2节涉及初始化,它解释了第2段处理成员查找和第7段查询参数的过程.
mem-initializer的表达式列表中的名称在为其指定mem-initializer的构造函数的范围内进行计算.[例:
class X {
int a;
int b;
int i;
int j;
public:
const int& r;
X(int i): r(a), b(i), i(i), j(this->i) {}
};
Run Code Online (Sandbox Code Playgroud)