static_assert не проходит проверку на шаблонном указателе объекта

template <size_t N>
class Foo
{
static_assert(N > 0, "WRONG");
//void Something() = 0; //my original implementation
};

int main() {

Foo<0> *p2 = nullptr;   //no error
Foo<0> p;   //gives an error

return 0;
}

Я проверил обе строки отдельно. static_assert не вызывается при инициализации p2, но вызывается и действительно завершается с ошибкой на p. Это предназначено? (Я пробовал это на gcc, clang и vc)

Каковы обходные пути? Поскольку я использую абстрактные шаблонные классы, было бы кошмаром, если утверждение выполняется только тогда, когда создается экземпляр объекта без указателя. Я могу использовать фабрику, но это не совсем правильное решение.

2

Решение

Вы наверняка видели эту цитату из §14.7.1 / 1:

Если специализация шаблона класса не была явно
созданный (14.7.2) или явно специализированный (14.7.3) класс
специализация шаблона неявно создается когда
На специализацию ссылаются в контексте, который требует
полностью определенный тип объекта или когда полнота класса
Тип влияет на семантику программы.

Типы указателя не требуют, чтобы их указатель был полным типом (например, void* является примером этого). Таким образом, первая строка не будет создавать экземпляр специализации, а вторая нужна, следовательно, утверждение относится только к этой.

Это также рассматривается в примере на три абзаца ниже:

[ пример:

template<class T> struct Z {
void f();
void g();
};

void h() {
Z<int> a;      // instantiation of class Z<int> required
Z<double>* q;  // instantiation of class Z<double> not required
//[…]
}

Ничто в этом примере не требует класса Z<double> […] Быть неявно созданным. — конец примера ]

6

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


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector