如何在C ++ 20'requires'表达式中使用未指定的类型? [英] How can unspecified types be used in C++20 'requires' expressions?

查看:114
本文介绍了如何在C ++ 20'requires'表达式中使用未指定的类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写C ++ 20概念来表达类型必须具有某种带参数的方法的要求,但是出于这个概念的目的,我不在乎参数类型是什么。

I'm trying to write a C++20 concept to express the requirement that a type have a certain method, which takes an argument, but for the purposes of this concept I don't care what the argument type is.

我试图写类似的东西:

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

但是,gcc和clang都拒绝了这一点,给出了一个错误,即'auto'不能在a的参数列表中使用

however, both gcc and clang reject this, giving an error that 'auto' cannot be used in the parameter list of a requires expression this way.

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

An alternative would be to put the type of 'x' as a second template parameter:

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

,但是这要求在使用概念时必须明确指定TX,无法推论:

but then this requires TX to be specified explicitly whenever the concept is used, it cannot be deduced:

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

有没有办法写出一个允许Foo接受参数的概念未指定类型?

Is there any way to write a concept that allows Foo to take an argument of unspecified type?

问题需要约束模板成员函数的概念定义非常相似,但不尽相同:该问题询问如何要求(模板化)方法可以采用满足给定概念的 any 类型,而这个问题是关于要求一种方法采用 some 特定类型的,尽管该类型未指定。在量词方面,另一个问题是关于(有界的)普遍量化的问题,而这是关于存在性量化的问题。另一个问题的答案也不适用于我的情况。

The question Concept definition requiring a constrained template member function is very similar, but not the same: that question asks how to require that a (templated) method can take any type satisfying a given concept, while this question is about requiring that a method takes some particular type, although that type is unspecified. In terms of quantifiers, the other question is asking about (bounded) universal quantification while this one is about existential quantification. The other question's answer also does not apply to my case.

推荐答案

可以通过定义一个适配器类型来实现接近此目的可以隐式转换为(几乎)任何东西:

Something close to this can be accomplished by defining an adapter type that can implicitly convert to (almost) anything:

struct anything
{
    // having both these conversions allows Foo's argument to be either
    // a value, an lvalue reference, or an rvalue reference

    template <typename T>
    operator T&();

    template <typename T>
    operator T&&();
};

请注意,这些运算符不需要实现,因为它们只会在未评估的上下文中使用(实际上,

Note that these operators do not need to be implemented, as they will only be used in an unevaluated context (and indeed, they could not be implemented for all types T).

然后, HasFooMethod 可以写为:

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

这篇关于如何在C ++ 20'requires'表达式中使用未指定的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆