在编写自定义反射库时,我遇到了一个奇怪的编译器行为。但是,我能够使用非常简化的代码重现该问题。这是:
#include <iostream>
class OtherBase{};
class Base{};
/* Used only as a test class to verify if the reflection API works properly*/
class Derived : Base, OtherBase
{
public:
void Printer()
{
std::cout << "Derived::Printer() has been called" << std::endl;
}
};
/*Descriptor class that basically incapsulate the address of Derived::Printer method*/
struct ClassDescriptor
{
using type = Derived;
struct FuncDescriptor
{
static constexpr const auto member_address{ &type::Printer };
};
};
int main()
{
Derived derived;
auto address{ &Derived::Printer };
(derived.*address)(); // -> OK it compiles fine using the local variable address
(derived.*ClassDescriptor::FuncDescriptor::member_address)(); // -> BROKEN using the address from the descriptor class cause fatal error C1001 !
}
在尝试调试此问题时,我注意到:
- 仅当
Derived
具有多重继承时才会发生。 static constexpr const auto member_address{ &type::Printer }
如果我与之交换inline static const auto member_address{ &type::Printer }
它就可以了。
它只是一个编译器错误,还是我做错了什么?我可以在保留 constexpr 的同时解决这个问题吗?
请注意,我使用的是 MSVC 2017 和编译器版本 19.16.27024.1 所有编译器选项都是默认的,除了 /std:c++17 启用。
我知道将编译器版本更新到最后一个版本(我肯定会这样做)可能会解决这个问题,但现在我想更多地了解这个问题。