Статическое утверждение в специализации шаблона не выполняется, даже если оно не было создано - PullRequest
0 голосов
/ 02 сентября 2018

Следующий код прекрасно компилируется:

#include <type_traits>

template <typename T> struct dependent_true : std::true_type { };
template <typename T> struct dependent_false : std::false_type { };

template <bool B = false>
class X { static_assert(dependent_false<X>::value); };

template <>
class X<true> { static_assert(dependent_true<X>::value); };

int main() {
   X<true> x;
}

То есть static_assert в первичном шаблоне не оценивается. Наоборот, если я переключусь на:

template <bool B = false>
class X { static_assert(dependent_true<X>::value); };

template <>
class X<true> { static_assert(dependent_false<X>::value); };

int main() {
    X<false> x;
}

Тогда статическое утверждение в специализации шаблона не выполняется, даже если оно не было создано. Мне просто интересно, почему. Я наблюдал такое поведение с GCC 8 и Clang 6 (-std=c++17).

Демонстрация в реальном времени: https://wandbox.org/permlink/MOWNLnGMgmuDA2Ht

Ответы [ 2 ]

0 голосов
/ 02 сентября 2018

template <> class X<true> {/* ... */}; - больше не шаблон.

[temp.expl.spec] / 5

Член явно специализированного класса не является неявно создается из объявления члена шаблона класса; вместо этого член специализации шаблона класса должен сам быть явно определенным, если требуется его определение. В этом случае Определение шаблона класса явной специализации должно быть в область действия в точке, в которой элемент определен. Определение явно специализированный класс не связан с определением сформированная специализация . То есть его члены не должны иметь одинаковые имена, типы и т. д. как члены сформированной специализации. Члены явно специализированного шаблона класса определены в так же, как и члены обычных классов, и не использует шаблон <> синтаксис. То же самое верно при определении члена явно специализированный член класса. Тем не менее, шаблон <> используется при определении член явно специализированного шаблона класса члена, который специализированный как шаблон класса.

Специализация похожа на обычный класс. Это не шаблон, и ничего не зависит. Следовательно, dependent_false<X>::value - это просто константное выражение, которое сразу же становится ложным Таким образом, статическое утверждение немедленно срабатывает.

0 голосов
/ 02 сентября 2018

Даже неинстанцированные части шаблона должны быть действительным кодом C ++. static_assert(false) делает программу некорректной. Таким образом, у вас есть специализация с static_assert, которая на момент компиляции известна как false, и ваша программа становится плохо сформированной. У вас нет неразрешенных параметров шаблона в вашем классе, который используется в static_assert, чтобы удивить компилятор; он точно знает, что это false.

То же самое относится к if constexpr, вы также не можете использовать static_assert с выражениями, о которых известно, что они ложные, даже если часть, в которой находится static_assert, всегда отбрасывается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...