ale*_*lex 2 c++ inheritance templates casting reference
在转换引用时,似乎编译器尝试将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"
}
Run Code Online (Sandbox Code Playgroud)
为什么不能像这样使用自定义转换?是否有可能实现预期的行为(使用引用"向上转换"到不可到达的基础)?
[class.conv.fct]/1读取(强调我的):
转换函数从不用于将(可能是cv限定的)对象转换为(可能是cv限定的)相同的对象类型(或对它的引用),转换为该类型的(可能是cv限定的)基类(或引用它)或(可能是cv-qualified)void.
确实clang发出警告:
warning: conversion function converting 'Derived' to its base class 'Base' will never be used
operator Base&() {
^
Run Code Online (Sandbox Code Playgroud)
指针没有这样的限制,因此static_cast<Base*>(d)工作并调用自定义转换运算符.
如果您确实想要使用转换运算符作为引用,则必须显式调用它:
std::cout << dRef.operator Base&().fn() << std::endl;
Run Code Online (Sandbox Code Playgroud)
但在这种情况下,你可能想要为它创建一个普通的成员函数,或者说实话,只需将继承公之于众.