Я недавно работал над библиотекой C++, где я разрабатывал класс шаблонов, который по соображениям эффективности и безопасности должен был быть специально неполиморфным. Чтобы впоследствии я не забыл об этом и случайно сломал все, я подумал, что буду хорошим гражданином и добавлю статическое утверждение на этот счет.Обеспечение того, что класс шаблонов не является полиморфным?
Первоначально я пытался что-то вроде этого:
template <typename T> class VirtualVerboten {
...
static_assert(!std::is_polymorphic<VirtualVerboten>::value,
"This should not be polymorphic."); // Error!
};
Это не компилируется, потому что, в то время, что я использую VirtualVerboten
, это неполный тип. Если бы это был класс, не шаблон, я бы просто поставить static_assert
сразу после типа:
class NonTemplateVirtualVerboten {
...
}
static_assert(!std::is_polymorphic<NonTemplateVirtualVerboten>::value,
"This should not be polymorphic.");
Но поскольку это шаблонный класс, аналогичная идея создания «шаблона static_assert
» не является юридическим :
template <typename T> class VirtualVerboten {
...
};
template <typename T>
static_assert(!std::is_polymorphic<VirtualVerboten>::value,
"This should not be polymorphic."); // Error!
решение, которое я придумал было найти функцию члена внутри VirtualVerboten
, что, вероятно, будет использоваться, когда шаблон был экземпляр (в частности, конструктор), а затем положить статическое утверждение там:
template <typename T> class VirtualVerboten {
VirtualVerboten();
};
template <typename T>
VirtualVerboten<T>::VirtualVerboten() {
static_assert(!std::is_polymorphic<VirtualVerboten>::value,
"This should not be polymorphic."); // Yay!
doSomeActualThingsAtRuntime();
}
Это работает, за исключением того, что он полагается на то, что этот конкретный конструктор будет фактически вызван и, следовательно, создан, что не удается, если есть несколько конструкторов, которые можно было бы назвать.
Есть ли «надежный» способ добавить это статическое утверждение здесь? Я понимаю, почему исходный код вызывал ошибку и почему у вас не может быть статического утверждения шаблона, так что это скорее «я пропустил другой способ сделать это?». а не «вот почему то, что вы сделали, не работает».
UHH? Конструктор? Нужно как-то конструировать класс. Наденьте свое статическое утверждение там. –
@SamVarshavchik Вот что я в итоге сделал. Возможно, я должен отредактировать вопрос, чтобы сделать это более ясным. – templatetypedef
Вам просто нужно упаковать тип во что-то зависимое, поэтому статическое утверждение проверяется только во второй фазе. –