c ++ 1z动态异常规范错误

Pus*_*try 13 c++ exception-specification c++17 gcc7

我正在尝试使用新的GCC版本7.2.1编译我的项目,并且遇到动态异常规范的问题:

error: ISO C++1z does not allow dynamic exception specifications
  MEMORY_ALLOC_OPERATORS(SQLException)
Run Code Online (Sandbox Code Playgroud)

问题是这些错误来自我无法控制的第三方库.

有没有办法解决它?据我所知,我不能告诉编译器用警告替换错误.使用--std=c++14不是一个选项,因为我想使用C++ 1z的新功能.

Bar*_*rry 9

由于P0003,C++ 17删除了动态异常规范.在此之前,自C++ 11以来,它们已被弃用.它们不再是语言的一部分,因此没有办法解决它.只要你需要第三方库,直到它发生变化,你就会陷入C++ 14.


如果你很绝望,你可以尝试:

#define throw(...)
Run Code Online (Sandbox Code Playgroud)

但我不推荐它.

  • 也许最好的方法是在库上隔离层(编译为C++ 14),为程序公开C++ 17接口? (5认同)

Wol*_*DEV 5

好吧,我写了一些解决方法。

#if __cplusplus >= 201703L
    /* MySQL override. This needed to be inclided before cppconn/exception.h to define them */
    #include <stdexcept>
    #include <string>
    #include <memory>

    /* Now remove the trow */
    #define throw(...)
    #include <cppconn/exception.h>
    #undef throw /* reset */
#endif
Run Code Online (Sandbox Code Playgroud)

简短说明:如果我们使用的是c ++ 17,则在分配器上不再允许throw。如果您仔细查看该库的标头,您会看到有一个定义的宏,其中包含该库中默认分配器的定义。可悲的是,它不能被覆盖,因为它在那里被定义而忽略了已经被定义的情况。因此,无论如何,您都必须覆盖该拖曳。

一个基本的技巧是用宏覆盖trow函数。这样做导致我们遇到一个问题,即我们还重写了库中所有包含的trow运算符,这不是一个好的解决方案(并且也不起作用)。如您所知,如果要包含标头,则它只会被包含一次(主要是由于标头保护)。因此,窍门是包括库所包含的标头,而不是覆盖目标库的标头,而抛出则不包含目标库的标头,因为我们已经这样做了。