Ну ... Я не понимаю, что вы имеете в виду под
[[temp.res.8.1]] Не применяется, потому что существует действительная специализация, в частности, допустимы только OnlyNumbersи может использоваться внутри класса, например, для определения переменной указателя члена (ptr).
Можете ли вы привести пример OnlyNumers
действительного и компилирующего основного шаблона на основе OnlyNumbers<C>
?
В любом случае, мне кажется, что дело именно в этом.
Если вы спросите
Это безопасный, совместимый со стандартами способ заставить конкретный шаблон [class] * не скомпилироваться с использованием static_assert, если ** и только если он создан?
мне кажется, что (возможно, исключая тест, который является верным, только если другая специализация соответствует), ответ "нет" из-за [temp.res.8.1].
Может бытьВы могли бы открыть небольшую открытую дверь, чтобы разрешить создание экземпляра, но доступен только тот, кто действительно (действительно!) хочет создать его экземпляр.
Например, вы можете добавить третий параметр шаблона с другим значением по умолчанию и что-то ещеследующим образом
template<typename T, typename U = void, typename V = int>
struct OnlyNumbers
{
static_assert(std::is_same<T, U>::value, "test 1");
static_assert(std::is_same<T, V>::value, "test 2");
};
Таким образом, вы открываете дверь для законной инстанции
OnlyNumbers<Foo, Foo, Foo> o1;
OnlyNumbers<void, void, void> o2;
OnlyNumbers<int, int> o3;
, но эксплицируете хотя бы второй тип шаблона.
В любом случае, зачемВы просто избегаете определятьосновная версия шаблона?
// declared but (main version) not defined
template<typename T, typename = void>
struct OnlyNumbers;
// only specialization defined
template<typename T>
struct OnlyNumbers<T, std::enable_if_t<std::is_arithmetic_v<T>>>
{ };