【问题标题】:Namespace alias in c++C++ 中的命名空间别名
【发布时间】:2017-01-02 01:53:22
【问题描述】:

我使用 c++11,而我需要 c++17 库中的一些类。在使用添加了哪些类的 boost 时,我希望执行以下操作:

#if __cplusplus < CPP17
using std::any = boost::any;  
#endif

不允许使用这样的别名。扩展 std 命名空间也会导致 undefined behaviour。我希望我的代码看起来与 c++ 版本相同。有没有明确的方法?

【问题讨论】:

  • 只需使用您自己的名字并根据需要为其分配boost::anystd::any

标签: c++ c++11 namespaces


【解决方案1】:

明确的方法是为其添加自定义名称。

#if __cplusplus < CPP17
using my_any = boost::any;
#else
using my_any = std::any;    
#endif

// using my_any...

【讨论】:

  • 我希望使用 std::any 来实现 c++17 的兼容性。
  • @Ariel 正如你所意识到的,合法地“修改” std 命名空间是不可能的。
【解决方案2】:

您似乎正在尝试在命名空间中创建类型别名。正确的语法是:

namespace namespace_name {
    using any = boost::any;
}

但是,标准不允许将定义(模板特化的例外)添加到 std 命名空间中,因此如果您尝试定义 std::any,程序的行为将是未定义的。

使用任何命名空间,包括全局命名空间都可以,但不能使用保留给实现的命名空间,包括std 及其子命名空间。

【讨论】:

  • 我尝试在std命名空间中添加定义,它被编译了。
  • @Ariel 我已经修改了我的答案。 std 中的定义不会使程序格式错误,它会使行为未定义。也就是说,格式不正确并不能保证阻止程序编译。
  • 很遗憾,当我从旧 c++ 版本切换到新版本时,我必须更改 'std' 中的所有 'boost'。
  • @Ariel 您可以使用预处理器宏为 boost 或标准创建 typedef,具体取决于标准版本。
  • @Ariel 看来宋元瑶的回答已经有例子了。
【解决方案3】:

我认为未定义的行为担忧有什么大不了的。您已经使用 #if 来检查 C++17,并且您知道在此之前没有 any。如果你真的想要这个,我说去吧,如果它早于 C++17,则将别名放在 std 中。

在一天结束时,辅助函数/类/等可能会被放置在另一个命名空间中或以 __ 为前缀,因为标准库可以使用它。我认为 C++17 之前的任何实现都不会在 std 中导出 any

没有其他办法。只要忽略“未定义的行为”,如果它有效,就去做。破坏您的代码并没有什么神奇之处。可能发生的最糟糕的情况是,当您定义别名时,错误的 std 实现会发生冲突并无法编译。在我看来,有些人夸大了未定义的行为问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-02
    • 2010-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-18
    相关资源
    最近更新 更多