我正在尝试编写一个 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
上;它在 T
和 X
之间的关联上。
概念并不意味着在真空中工作,与约束的实际使用位置没有任何关联。您不应该专注于创建一元概念,以便用户可以针对它们static_assert
他们的类。概念不是为了测试一个类型是否满足它们(这基本上就是你的 static_assert
正在做的);它们用于限制使用它们的模板定义。
您的约束需要是 FooCallableWith
,而不是 HasFooMethod
。
关于c++ - 如何在 C++20 'requires' 表达式中使用未指定的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63443702/