如何通过禁用专业化本身的类型参数来限制类模板,为什么(n' t)它起作用?

发布于 2025-01-26 15:22:18 字数 1699 浏览 3 评论 0原文

当前是否有可能约束拒绝类型参数的类模板,哪些是类模板本身的专业化,而无需使用static_assert

由于我不能使用需要表达式来检查它是否是有效的类型名称,因此我必须创建一个类模板实例化验证器,该类别验证器检查类模板是否对模板参数有效:

template <template <typename...> typename Temp, typename... Ts>
    requires requires { typename Temp<Ts...>; }
constexpr bool is_valid() { return true; }

template <template <typename...> typename, typename...>
constexpr bool is_valid() { return false; }

template <template <typename...> typename Temp, typename... Ts>
concept valid_instantiation = is_valid<Temp, Ts...>();

由于失败statatic_assert像这样发出的硬错误:

template <typename>
class Hello;

template <typename>
inline constexpr bool is_hello_v = false;

template <typename T>
inline constexpr bool is_hello_v<Hello<T>> = true;

template <typename T>
class Hello {
  static_assert(!is_hello_v<T>);
};

static_assert(valid_instantiation<Hello, int>);
static_assert(!valid_instantiation<Hello, Hello<int>>);

第二个静态断言肯定不会编译,除非我删除返回true true 不是我的预期的。

我想拥有的是保持错误并替换static_assert,以便:

static_assert(valid_instantiation<Hello, int>);
static_assert(!valid_instantiation<Hello, Hello<int>>);

可以有效。

对于第一个静态断言,hello&lt; int实例化就可以接受,而第二个静态断言,hello&hello&hello&lt; hello&lt; int&gt; gt;应拒绝,因为应该被拒绝传递的模板参数是类模板本身的实例化,但我不知道我将使用什么约束来实现这些限制。

如果不可能这样做,或者其他情况是可以的。

Is it currently possible to constrain a class template that rejects type argument which is the specialization of the class template itself without using static_assert?

Since I cannot use requires expression to check if it is a valid typename, I have to create a class template instantiation validator that checks whether the class template passed is valid with template arguments:

template <template <typename...> typename Temp, typename... Ts>
    requires requires { typename Temp<Ts...>; }
constexpr bool is_valid() { return true; }

template <template <typename...> typename, typename...>
constexpr bool is_valid() { return false; }

template <template <typename...> typename Temp, typename... Ts>
concept valid_instantiation = is_valid<Temp, Ts...>();

Since failed static_assert emits a hard error, just like this one:

template <typename>
class Hello;

template <typename>
inline constexpr bool is_hello_v = false;

template <typename T>
inline constexpr bool is_hello_v<Hello<T>> = true;

template <typename T>
class Hello {
  static_assert(!is_hello_v<T>);
};

static_assert(valid_instantiation<Hello, int>);
static_assert(!valid_instantiation<Hello, Hello<int>>);

The second static assertion sure didn't compile unless I remove that ! that returns true which is not what I expected.

What I want to have is to silent the error and replace the static_assert, so that:

static_assert(valid_instantiation<Hello, int>);
static_assert(!valid_instantiation<Hello, Hello<int>>);

can be valid.

For the first static assertion, the Hello<int> instantiation is accepted just fine, while the second static assertion, Hello<Hello<int>> instantiation should be rejected because the template argument passed is the instantiation of the class template itself but I have no knowledge what constraints I'll be using to achieve these.

It's ok if it is impossible to do so, or otherwise.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

半岛未凉 2025-02-02 15:22:18

不确定这是您想要的,但

template <typename T> struct is_Hello;
template <typename T> requires (!is_Hello<T>::value) class Hello;

template <typename T> struct is_Hello : std::false_type{};
template <typename T> struct is_Hello<Hello<T>> : std::true_type{};

template <typename T>
requires (!is_Hello<T>::value) // So Hello<Hello<T>> is not possible
class Hello
{
// ...
};

不确定您要如何进行Sfinae或测试(特质似乎是等效的),因为hello&hello&lt; hello&lt; t&gt;&gt; 不存在。

demo

Not sure it is what you want, but

template <typename T> struct is_Hello;
template <typename T> requires (!is_Hello<T>::value) class Hello;

template <typename T> struct is_Hello : std::false_type{};
template <typename T> struct is_Hello<Hello<T>> : std::true_type{};

template <typename T>
requires (!is_Hello<T>::value) // So Hello<Hello<T>> is not possible
class Hello
{
// ...
};

Not sure how you want to SFINAE or test it (the trait seems equivalent), as Hello<Hello<T>> cannot exist.

Demo

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文