Продолжая Почему 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;
}
рассматривать
bool const* g_b= &all_true_v<true>;
это будет иметь тот же адрес в каждой единице перевода для inline constexpr
версия, но разные адреса для namespace {}
версия.
Вы избегаете нарушения ODR с помощью анонимного пространства имен, так как оно создает новый отдельный набор объектов в каждом файле, в который оно включено. Преимущество inline
Объект в том, что будет только один всего.
Однако, если вы используете только constexpr
значения как константы, вы не заметите большой разницы. И хороший компилятор может избежать хранения констант в области данных в любом случае.
Передача ссылок или указателей и сравнение адресов могут иметь значение, как говорит Тоби. Но, возможно, вы можете избежать сравнения адресов двух постоянных значений?