C++11 私有成员的聚合初始化,正确吗?
C++11 Aggregate initialization of private member, is it correct?
在将私有成员作为参数传递给所有者的 class 函数时,通过聚合初始化来初始化私有成员是否正确?看看下面的代码。
class A {
struct S {
int t, u;
};
public:
void f(const S& s) {}
};
int main() {
A a;
a.f({1, 2}); // correct?
return 0;
}
我查了standard和nets,好像没有确切的答案。看起来机制如下:
* 大括号初始化器是 public 的东西,因此用户不会违反访问限制。
* 从初始值设定项到 "S" 的隐式转换对于 "S" 是内部的,因此对于编译器也很好。
问题是,在标准、草案或至少 cppreference 中是否有一些关于此行为描述的参考?
是的,这是正确的。 S
唯一不公开的是名字。访问控制仅通过名称 ([class.access]p4). So you could use a type trait to get the type of S
for example through f
's type (example) 来控制访问。
所以,这是允许的,因为没有限制 [dcl.init.agg] 禁止初始化 "private" 类型。
还有 a note,由@StephaDyatkovskiy 找到。
官方是否有效并不重要;你应该避免这种极端情况。
我会说 "is it valid C++" 是错误的问题。
当您查看一段代码并尽可能尝试时,您无法决定它是否应该是有效的 C++;并且您知道这将是一些极端情况,具体取决于标准的确切措辞 - 无论哪种方式,通常都不要依赖该极端情况通常是个好主意。为什么?因为其他人也会感到困惑;他们会浪费时间去理解你的意思;他们会在标准中查找它——或者更糟的是,不查找它,并做出无效的假设;他们会从他们真正需要关注的事情上分心。
所以,使用这段代码,我会问自己:"Is type S
really private? Does outside code really not need to know about it?"
如果答案是 "Yes, it is" - 那么我会更改 f
,以获取 S 构造函数的参数(并将它们转发给 ctor):
void f(int t, int u) { S {t, u}; /* etc. etc. */ }
如果答案是 "No, code calling f()
can know that it's passing an S
reference" - 那么我会 S
public.
在将私有成员作为参数传递给所有者的 class 函数时,通过聚合初始化来初始化私有成员是否正确?看看下面的代码。
class A {
struct S {
int t, u;
};
public:
void f(const S& s) {}
};
int main() {
A a;
a.f({1, 2}); // correct?
return 0;
}
我查了standard和nets,好像没有确切的答案。看起来机制如下: * 大括号初始化器是 public 的东西,因此用户不会违反访问限制。 * 从初始值设定项到 "S" 的隐式转换对于 "S" 是内部的,因此对于编译器也很好。
问题是,在标准、草案或至少 cppreference 中是否有一些关于此行为描述的参考?
是的,这是正确的。 S
唯一不公开的是名字。访问控制仅通过名称 ([class.access]p4). So you could use a type trait to get the type of S
for example through f
's type (example) 来控制访问。
所以,这是允许的,因为没有限制 [dcl.init.agg] 禁止初始化 "private" 类型。
还有 a note,由@StephaDyatkovskiy 找到。
官方是否有效并不重要;你应该避免这种极端情况。
我会说 "is it valid C++" 是错误的问题。
当您查看一段代码并尽可能尝试时,您无法决定它是否应该是有效的 C++;并且您知道这将是一些极端情况,具体取决于标准的确切措辞 - 无论哪种方式,通常都不要依赖该极端情况通常是个好主意。为什么?因为其他人也会感到困惑;他们会浪费时间去理解你的意思;他们会在标准中查找它——或者更糟的是,不查找它,并做出无效的假设;他们会从他们真正需要关注的事情上分心。
所以,使用这段代码,我会问自己:"Is type S
really private? Does outside code really not need to know about it?"
如果答案是 "Yes, it is" - 那么我会更改 f
,以获取 S 构造函数的参数(并将它们转发给 ctor):
void f(int t, int u) { S {t, u}; /* etc. etc. */ }
如果答案是 "No, code calling f()
can know that it's passing an S
reference" - 那么我会 S
public.