c++ - 不受约束的 requires-expression 参数

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

我能否在概念的 C++20 约束中使用受约束的泛型类型?例如,假设我想写一个要求,候选类 T 有一个函数 func,它可以接受满足 std 的任何类型的参数::范围::范围:

template<typename T>
concept Foo = requires (T t, std::ranges:range s) {
    { t.func(a); } -> std::convertible_to<double>;
}

但是 GCC 给我一条错误消息,指出不能在我放置 std::ranges::range 的地方使用占位符类型。

最佳答案

在我看来,您正在寻找一个带有(仅声明的)operator T () 的结构,用于通用 T

struct generic_argument
 {
   template <typename T>
   operator T () const;
 };

因此您可以为每个预期参数和模板参数传递它(在 decltype() 中)。

所以你的概念(抱歉......我简化了它删除了范围参数)变成了(如果我明白你想要什么)

template<typename T>
concept Foo 
   = std::convertible_to<decltype(std::declval<T>().func(std::declval<generic_argument>())),
                         double>;

下面是一个完整的编译示例

#include <iostream>

struct A { double func (int a) { return a; } };
struct B { double not_func (long a) { return a; } };
struct C { std::string func (char) { return "abc"; } };
struct D { float func (auto) { return 1.0f; } };

struct E { double func (int a) { return a; }
           std::string func (char) { return "abc"; } };

struct generic_argument
 {
   template <typename T>
   operator T () const;
 };

template<typename T>
concept Foo 
   = std::convertible_to<decltype(std::declval<T>().func(std::declval<generic_argument>())),
                         double>;

template <Foo T>
void bar (T const &)
 { std::cout << "bar, Foo version\n"; }

template <typename T>
void bar (T const &)
 { std::cout << "bar, generic version\n"; }

int main()
 {
   bar(A{}); // print bar, Foo version
   bar(B{}); // print bar, generic version [no func() function]
   bar(C{}); // print bar, generic version [no convertible to double]
   bar(D{}); // print bar, Foo version
   bar(E{}); // print bar, generic version [two func() function]
 }

我对 E 的情况有疑问:两个 func() 方法,一个只返回一个可转换为 double 的类型,来自bar(E{}) 我们得到“bar, generic version”。

关于c++ - 不受约束的 requires-expression 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66994909/

相关文章:

c++ - 读取空格会使解析器崩溃。为什么?

c++ - 将基于范围的 for 循环与第三方容器结合使用

c++ - 匿名结构中声明的函数的名称解析

c++ - - 9'223' 37 2'036' 85 4'775' 808LL 未签名

C++概念不好用?

c++ - 如何限制C++中rand函数生成的数字

c++ - 在索引和值类型上参数化的惯用 vector 类型

c++ - 导入模块的标准方式

c++ - 使用 C++ 概念实现强类型的特征

c++ - 概念 std::equality_comparable_with 不适用于用户定义的相等运算符