已知基类A,如何在编译期确定类型X可转换到的派生类B?
能否通过类型X和基类A在编译期确定转换目标类型B?
这个问题问得很有深度!咱们先从你给出的示例代码入手:
struct A {}; struct B : A{}; struct X { operator B() {return {};} }; int main() { A a = X{}; }
在这段代码里,A a = X{};能正常编译运行,是因为X的operator B()被调用,生成的B对象又隐式转换为基类A。你的疑问是:如果只知道类型X和基类A,能不能编写一个类型特征foo_t<X, A>,让它的结果等于B?
结论:做不到
原因主要有以下几点:
转换目标不唯一:
假设X可以转换到多个A的派生类,比如:struct A {}; struct B : A {}; struct C : A {}; struct X { operator B() { return {}; } operator C() { return {}; } };这时候
A a = X{};会直接编译失败——因为编译器无法确定该选择operator B()还是operator C()。反过来,我们的类型特征foo_t<X, A>也不可能确定出唯一的B,因为存在多个符合条件的候选类型。转换路径可能有多层:
就算X只有一个转换函数,它的目标类型也不一定是A的直接派生类。比如:struct A {}; struct B : A {}; struct D : B {}; struct X { operator D() { return {}; } };此时
A a = X{};依然能正常运行:X转成D,D通过继承关系隐式转成B,再转成A。这时候你期望的B其实是转换路径中的中间类型,但编译器的重载决议只会找到operator D(),我们没办法通过类型特征提取出“路径中的某个基类”。标准未提供相关查询机制:
C++的类型特征系统只能查询类型的固有属性(比如是否是类、是否继承自某类等),但重载决议的结果是依赖于具体表达式的,不属于类型的固有属性。我们没办法通过类型特征去反向推导“当X转换到A时,会调用哪个转换函数”,更没法提取该函数的返回类型。
所以,不存在一种可靠的方式编写foo_t<X, A>来确定你想要的B类型。
内容的提问来源于stack exchange,提问作者HolyBlackCat
相关产品推荐
相关产品推荐

