编写非虚拟条件成员函数是否安全?

时间:2012-07-27 15:16:55

标签: c++ oop c++11 c-preprocessor

  1. [二元]安全吗?

    struct Foo {
    
        #if __cplusplus > 199711L
            Foo( std::initializer_list<int> & list ) {
                /* ... */
            }
        #endif
    
    };
    

    我见过this topic, 但OP原始问题没有得到解答。

  2. 有没有更好的方法来实现这种行为?

2 个答案:

答案 0 :(得分:0)

它可能很好,DirectX结构是以这种方式实现的,但它完成了支持C和C ++。

答案 1 :(得分:0)

我假设你:

  • 将这样的代码编译成一个库,一直在升级您的编译器,现在想用C ++ 11编译代码(或者因为你没有代码而不能编译代码),或者,

  • 在C ++ 11之前的库中已经存在代码,现在您已经升级了要使用上述代码的编译器,并且与旧库“兼容”,或者

  • 想要编译没有C ++ 11的代码,并使用相同的编译器将其与使用C ++ 11编译的代码链接。

在每种情况下,答案都不是C ++问题,而是一个编译器ABI问题,因为它涉及(i)链接阶段是否有效以及(ii)类的运行时形式等。在编译器/版本/编译器设置之间仍然有效。

因此,您需要检查您正在使用的编译器的文档,以确定它是否是“二进制安全”。

注意#1:如果您的编译器(/)已经以任何方式更改了异常处理发出的代码设计,类的RTTI布局和/或名称修改方案,那么你的回答是,“不,这不安全。”但这些可能不是唯一的情况。

注意#2:如果它使用相同的编译器和不同的设置(例如,使用C ++ 11和不使用),那么从技术上讲,当您排除时,您在技术上违反了ODR(一个定义规则)假设某些模块的代码,并将其用于同一程序中的其他模块。在这种情况下,结果是技术上实现定义的,但是,由于它不是虚拟的,因此只使用一个编译器的一个版本,它就非常非常非常可能与大多数编译器一起工作。