在匿名命名空间中定义全局constexpr变量与将它们内联定义相同吗?

时间:2018-01-03 13:02:00

标签: c++ c++17 inline-variable

跟进Why does cppreference define type_traits xxx_v shortcuts as inline constexpr and not just constexpr?,如果我创建自己的类型特征并希望避免ODR违规并希望它与前C ++ 17项目兼容,那么将xxx_v快捷方式放在匿名命名空间中与明确声明内联相同吗?

例如,从Check traits for all variadic template arguments获取all_true,使用C ++ 17我可以在我的实用程序标题中写入:

template <bool...> struct bool_pack;
template <bool... v>
using all_true = std::is_same<bool_pack<true, v...>, bool_pack<v..., true>>;
template <bool... v>
inline constexpr bool all_true_v = all_true<v...>::value;

是否与编写与C ++之前版本17兼容的以下代码相同?

template <bool...> struct bool_pack;
template <bool... v>
using all_true = std::is_same<bool_pack<true, v...>, bool_pack<v..., true>>;
namespace {
   template <bool... v>
   constexpr bool all_true_v = all_true<v...>::value;
}

2 个答案:

答案 0 :(得分:2)

考虑

    bool const* g_b= &all_true_v<true>;

inline constexpr版本的每个翻译单元都有相同的地址,但namespace {}版本的地址不同。

答案 1 :(得分:1)

您确实避免了使用匿名命名空间的ODR违规,因为它会在包含它的每个文件中创建一组新的独立对象。 inline对象的优点是总共只有一个。

但是,如果仅将constexpr值用作常量,则不会发现太大的差异。一个好的编译器可能会避免将常量存储在数据区域中。

传递引用或指针并比较地址可能会有所不同,就像Tobi说的那样。但也许你可以避免比较两个常数值的地址?