从未使用过的转换为基类

时间:2018-09-06 02:49:18

标签: c++ c++11 base-class explicit typecast-operator

我有两个类,一个是从另一个私有地派生的(因为我不想公开基础的接口)。但是,稍后我想创建对基准的引用。

我可以使用普通的成员函数base()来执行此操作,但是不能使用强制转换操作符来执行此操作,因为从不调用该操作符

clang警告它,因为它说“它永远不会被调用”。

为什么强制转换运算符被私有元素忽略并覆盖? 这是语言上的不一致吗?

实际上,我认为它具有一个使基本参考公开的特性,而没有别的。 更有效的话,可能是explicit

class A{
    int v_;
public:
    void f(){}
};

class B : A{ // A is private base because I don't want the f() interface
    int w_;
public:
    A const& base() const{return *this;}
    /*explicit*/ operator A const&() const{return *this;} // never called, warning in clang
};

int main(){
    A a = {};
    B b = {};
    A const& a2 = b.base();
    A const& a3 = b; // bad, But why?
    A const& a4{b}; // explict doesn't help
    A const& a5 = b.operator A const&(); // works in clang (but with a contradictory warning), doesn't work with gcc
}

1 个答案:

答案 0 :(得分:3)

a3a4情况下,您正在使用左值初始化引用。在这种情况下,如果引用的类型是初始值设定项类型的基类,则引用直接绑定到初始值设定项,不涉及任何转换(C ++ 17 [dcl.init.ref] / 5)。

由于无法访问基类,因此程序格式错误(dcl.init.ref / 4)。

我不确定a5中的访问检查规则,尽管在实践中似乎无济于事,因为您不会设计代码,因此有人必须编写该语法。

另请参阅[class.conv.fct] / 1:

  

从不使用转换函数将(可能具有cv限定)对象转换为(可能具有cv限定)相同对象类型(或对其的引用),转换为该对象的(可能具有cv限定)基类。键入(或对其进行引用)或(可能具有cv资格)作废。