Определить глобальные переменные constexpr в анонимном пространстве имен так же, как сделать их встроенными?

Продолжая Почему cppreference определяет ярлыки type_traits xxx_v как встроенный constexpr, а не просто constexpr?, если я создаю свою собственную черту типа и хочу избежать нарушений 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;

Это то же самое, что написать следующий код, совместимый с pre-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;
}

0

Решение

рассматривать

    bool const* g_b= &all_true_v<true>;

это будет иметь тот же адрес в каждой единице перевода для inline constexpr версия, но разные адреса для namespace {} версия.

2

Другие решения

Вы избегаете нарушения ODR с помощью анонимного пространства имен, так как оно создает новый отдельный набор объектов в каждом файле, в который оно включено. Преимущество inline Объект в том, что будет только один всего.

Однако, если вы используете только constexpr значения как константы, вы не заметите большой разницы. И хороший компилятор может избежать хранения констант в области данных в любом случае.

Передача ссылок или указателей и сравнение адресов могут иметь значение, как говорит Тоби. Но, возможно, вы можете избежать сравнения адресов двух постоянных значений?

1

По вопросам рекламы [email protected]