我正在开发一个通过模板使用静态多态性的 C++ 库。如此设计是因为目标是具有小型堆栈的嵌入式系统,并且通常有益于 inline
成员函数以节省堆栈使用。
使用静态多态性模板意味着事件发射器(最常见的是设备驱动程序)的类型名称通常非常长:
class DeviceThatUsesSPI<class SPI_BUS_TYPE> {
public:
class DeviceEvent : public Event<DeviceThatUsesSPI> {};
// and the rest of the device driver implementation, including
// the code that emits that event.
}
SomeSpecificGpioBus gpio_bus();
SoftwareSpiBus<typeof(gpio_bus)> spi_bus(&gpio_bus);
DeviceThatUsesSPI<typeof(spi_bus)> device(&spi_bus);
如您所见,我们使用 GCC typeof
扩展运算符以避免写出完整的令人讨厌的类型名称 DeviceThatUsesSPI<SoftwareSpiBus<SomeSpecificGpioBus>>
反复。这在我们尝试过的任何地方都非常有效,直到今天我尝试使用它来访问表示事件的嵌套类。在我当前的示例中,这是一个模板特化,实现编译时事件处理程序绑定(bind):
template<>
inline void event_handler<typeof(device)::ExampleEvent>(typeof(device) *emitter) {
// event handler implementation...
}
但是,我也在变量声明的一个更简单的示例中尝试过这一点:
typeof(device)::ExampleEvent event;
在这两种情况下,G++ 都无法解析表达式并出现语法错误。我认为这是因为在标准 C++ 语法中不存在 ::
的情况。后面跟随除标识符之外的任何内容,并且解析器在遇到冒号时无法回溯并将第一部分视为类型。
但是,the GCC manual about typeof
对此运营商做出如下 promise :
A
typeof
construct can be used anywhere a typedef name can be used. For example, you can use it in a declaration, in a cast, or inside ofsizeof
ortypeof
.
如果我替换 typeof
的两个用途在我使用 typedef 的示例中,G++ 很高兴:
typedef typeof(device) device_type;
template<>
inline void event_handler<device_type::ExampleEvent>(typeof(device) *emitter) {
// event handler implementation...
}
device_type::ExampleEvent event;
因此,这进一步加深了我的怀疑,即编译器对我在语义上编写的内容没有问题,但语法不允许我表达它。虽然使用 typedef 间接确实可以让我工作代码,但我更愿意找到一种方法使事件处理程序声明独立,以方便该库的用户。有没有办法写typeof
运算符来消除解析歧义,以便我可以使事件声明成为单行代码?
最佳答案
根据a bug report against GCC这是一个已知问题,已在 GCC 4.7 中修复。升级GCC是长期解决方案。
错误报告描述了使用类模板作为间接方法来绕过旧版本中的解析器的进一步解决方法:
class SameType<T> {
public:
typedef T R;
}
T<typeof(device)>::ExampleEvent event;
这比 typedef 更好,因为它泛化到所有事件类型,但对于用户来说仍然不自然。
同样的问题,应用于新标准 decltype
运算符,实际上是 a C++11 specification change 的主题。澄清了类型解析的规则,使其按预期工作。
关于c++ - 将 GCC 的 typeof() 扩展与成员访问相结合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14669982/