在匿名命名空间中定义全局 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 说的那样,传递引用或指针并比较地址可能会有所不同。但是也许你可以避免比较两个常量值的地址?
跟进
例如,从 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 说的那样,传递引用或指针并比较地址可能会有所不同。但是也许你可以避免比较两个常量值的地址?