c++ - 如何在 C++20 'requires' 表达式中使用未指定的类型?

标签 c++ c++20 c++-concepts

我正在尝试编写一个 C++20 概念来表达类型具有特定方法的要求,该方法采用参数,但出于此概念的目的,我不关心参数类型是什么。

我试过这样写:

template <typename T>
concept HasFooMethod = requires(T t, auto x)
{
    { t.Foo(x) } -> std::same_as<void>;
};

然而,gcc 和 clang 都拒绝了这一点,给出了一个错误,即“auto”不能以这种方式用于 requires 表达式的参数列表中。

另一种方法是将“x”的类型作为第二个模板参数:

template <typename T, typename TX>
concept HasFooMethod = requires(T t, TX x)
{
    { t.Foo(x) } -> std::same_as<void>;
};

但这需要在使用该概念时明确指定 TX,无法推导:

struct S { void Foo(int); };
static_assert(HasFooMethod<S>);         // doesn't compile
static_assert(HasFooMethod<S, int>);    // the 'int' must be specified

有什么方法可以编写一个允许 Foo 接受未指定类型参数的概念吗?

问题Concept definition requiring a constrained template member function非常相似,但不相同:该问题询问如何要求(模板化的)方法可以采用满足给定概念的 any 类型,而这个问题是关于要求方法采用 某些 特定类型,尽管该类型未指定。在量词方面,另一个问题是询问(有界的)全称量化,而这个问题是关于存在量化的。另一个问题的答案也不适用于我的情况。

最佳答案

概念并非旨在提供您正在寻找的那种功能。 So they don't provide it.

概念旨在约束模板,指定模板打算在其定义中使用(或至少免费使用)的一组表达式或语句。

在您如此约束的模板中,如果您编写表达式t.Foo(x),那么您就知道x 的类型。它可以是具体类型、模板参数或派生自模板参数的名称。无论哪种方式,x 的类型在受约束的模板中可用。

所以如果你想约束这样一个模板,你同时使用t的类型和x的类型。那时两者都可用,因此创建这样的约束没有问题。也就是说,约束不在作为孤立类型的 T 上;它在 TX 之间的关联上。

概念并不意味着在真空中工作,与约束的实际使用位置没有任何关联。您不应该专注于创建一元概念,以便用户可以针对它们static_assert 他们的类。概念不是为了测试一个类型是否满足它们(这基本上就是你的 static_assert 正在做的);它们用于限制使用它们的模板定义。

您的约束需要是 FooCallableWith,而不是 HasFooMethod

关于c++ - 如何在 C++20 'requires' 表达式中使用未指定的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63443702/

相关文章:

c++ - 如何使概念失败并显示自定义错误消息(C++ 20)

c++ - 我如何使用树莓派获取ina219传感器数据

c++ - 与 OpenMP、MPI 和 CUDA 链接时的 Autotools 问题

c++ - 如何使用 gcc/g++ 11.1 导入模块

c++ - std::ranges::make_heap的约束是什么?

c++ - std::span 是 View 吗?

c++ - 如何在约束中使用 ADL?

c++ - XML 中的 UTF 8 编码日文字符串

c++ - Windows API : Detecting when a driver install has finished

C++20 概念 : Difference in the behavior of the compound requirement expression with a pointer-type member in GCC and Clang