C++ 操作员是否应保持基本和;()是否用于不可访问的基类?
我希望有一个类,它允许访问它的基本情况的const接口,但不允许访问其他情况。特别是:C++ 操作员是否应保持基本和;()是否用于不可访问的基类?,c++,c++11,c++14,C++,C++11,C++14,我希望有一个类,它允许访问它的基本情况的const接口,但不允许访问其他情况。特别是: class B {}; class A : private class B { public: operator const B&() { return *this; } }; int main() { A a; const B& b = a; // Should this line be an error? } g++给出了一个不可访问的基类错误。你们的语言专家认为这个错误
class B
{};
class A : private class B
{
public:
operator const B&() { return *this; }
};
int main()
{
A a;
const B& b = a; // Should this line be an error?
}
g++给出了一个不可访问的基类错误。你们的语言专家认为这个错误在C++11/C++14中是正确的吗
是的,我意识到我可以(也将)做到这一点:
int main()
{
A a;
const B& b = a.operator const B&();
}
对这种构造的另一种方法有什么建议吗 [dcl.init.ref]/5:
对类型“cv1T1
”的引用由以下表达式初始化
键入“cv2T2
”,如下所示:
- 如果引用是左值引用且初始值设定项
表情
- 是左值(但不是位字段),“cv1
”是与“cv2T1
”兼容的引用,或T2
- 有一个类类型(即,
是一个类类型),其中T2
与T1
无关,[…]T2
- 是左值(但不是位字段),“cv1
B
引用与A相关(并且与之兼容),即使它是一个私有基类,因此第一个要点适用。现在[dcl.init.ref]/4将此场景定义为格式错误:
给定类型“cv1T1
”和“cv1T2
”,“cv1T1
”是
如果T1
与T2
类型相同,则与“cv1T2
相关的参考,
或者T1
是T2
的基类。如果T1
参考与T2
和cv1相关,则“cv1T1
”参考与“cv2T2
”兼容
与cv2相同或大于cv2在引用相关的所有情况下
或使用两种类型的引用兼容关系来确定引用绑定的有效性,以及
T1
是T2
的基类,如果T1
是T2
的不可访问的[…]基类,则需要这种绑定的程序格式不正确
因此,无论任何可用的转换函数如何,此类引用绑定都将始终失败。引用绑定不能与私有继承一起使用
显式调用就是这个问题的解决方案,尽管不再需要转换运算符:只需定义一个返回const
-reference的getter即可。例如
const B& b = a.getB();
不调用A::operator const B&()
。此行为自C++03天起就存在。
这是一个简单的向上转换,从派生类型到基类型。此向上转换引发编译器错误,因为基(类B
)由全局范围内的派生(类A
)私有继承
如果B
和A
之间没有这样的继承关系,那么所提到的操作符const B&(()
肯定会按照您的期望实例化。错误是正确的。只有当类型与引用无关时,才会考虑隐式转换(在本例中,通过运算符)。继承关系意味着它们是,因此引用将直接绑定而不进行转换,但由于私有继承而失败
除非您有很好的继承理由,否则您可能会将设置为成员而不是基类。在这种情况下,返回对该成员的引用的转换运算符将执行您想要的操作
如果您确实需要继承,那么适当命名的函数可能比需要显式运算符调用更好。您已经有了说明这是错误的答案,但是,想想如果不是错误会发生什么:这意味着const B&B=a
的行为完全不同,这取决于它是否出现在a
的朋友中。为什么不只是组合而不是私有继承呢?
const B& b = a;