Рассмотрим этот код
template <typename T>
struct delay : std::false_type{};
template <typename T>
struct my_typelist {
static_assert(delay<T>{}, "");
};
template <typename Tuple>
struct test;
template <typename T>
struct test<my_typelist<T>> {
void pass(){}
};
template <typename T>
void fail(const test<T> &){}
int main()
{
test<my_typelist<int>> t;
t.pass();
fail(t);
}
Без вызова fail()
код компилируется и работает нормально. Однако использование t
в любой функции, по-видимому, вызывает static_assert
в классе my_typelist
, хотя класс никогда не создается. Хотя этот пример надуман, я столкнулся с той же проблемой, используя неполные типы внутри std::tuple
, хотя я просто использовал std::tuple
как список типов и никогда не создавал его.
Почему триггер static_assert
срабатывает только после использования переменной в качестве параметра, а не при вызове функции-члена? В каких контекстах создается my_typelist
, а когда нет?
Обратите внимание, что я использовал бы вариационный шаблон, но ошибка возникает независимо от этого, поэтому я решил использовать самый низкий общий знаменатель.