在转换引用时,似乎编译器尝试将Derived
类转换为其Base
并且根本不使用自定义转换。尽管如此,这仍然完美无缺。
示例:
#include <iostream>
class Base {
public:
int fn() {
return 42;
}
};
class Derived : private Base {
public:
operator Base&() {
return *dynamic_cast<Base*>(this);
}
operator Base*() {
return dynamic_cast<Base*>(this);
}
};
int main() {
Derived d;
Derived &dRef = d;
std::cout<<static_cast<Base&>(dRef).fn()<<std::endl; // <-- error: non-reachable base >>Base<< of >>Derived<<
std::cout<<static_cast<Base*>(d)->fn()<<std::endl; // OK -> "42"
}
为什么不能像这样使用自定义转换?是否有可能实现预期的行为(使用引用“向上转换”到不可到达的基础)?
答案 0 :(得分:5)
[class.conv.fct] / 1读取(强调我的):
转换函数永远不会用于将(可能是cv限定的)对象转换为(可能是cv-qualified) 相同的对象类型(或对它的引用),到该类型的(可能是cv限定的)基类(或对该类型的引用) it),或(可能是cv-qualified)void。
确实clang发出警告:
warning: conversion function converting 'Derived' to its base class 'Base' will never be used
operator Base&() {
^
指针没有此类限制,因此static_cast<Base*>(d)
可以使用并调用自定义转化运算符。
如果您确实想要将转换运算符用于引用,则必须明确调用它:
std::cout << dRef.operator Base&().fn() << std::endl;
但是在这种情况下,你可能想要为它创建一个普通的成员函数,或者说实话,只需公开继承。