在匿名命名空间中定义全局 constexpr 变量与使它们内联一样吗?

Defining global constexpr variables in anonymous namespace the same as making them inline?

跟进 ,如果我创建自己的类型特征并希望避免 ODR 违规并希望它与 C++17 之前的项目兼容,则将 xxx_v匿名命名空间中的快捷方式与显式内联声明一样吗?

例如,从 中获取 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;
}

考虑

    bool const* g_b= &all_true_v<true>;

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

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

但是,如果您只使用 constexpr 值作为常量,您将不会注意到太大的差异。一个好的编译器可能会避免将常量存储在数据区域中。

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