C++ 约束类模板函数以接受特定的POD类型

C++ 约束类模板函数以接受特定的POD类型,c++,c++20,c++-concepts,C++,C++20,C++ Concepts,我正在自学C++20的新概念特性,当我试图确保必须存在的成员函数只接受特定类型时遇到了一个障碍。我发现了这一点,它向我展示了如何确保任何功能都可以存在。然后我想进一步确保有一个带有特定参数的函数存在。我首先定义类型T必须有一个返回int的函数号 #include <concepts> template <typename T> concept MyRequirement = requires (T t) { { t.number(int) } -> st

我正在自学C++20的新概念特性,当我试图确保必须存在的成员函数只接受特定类型时遇到了一个障碍。我发现了这一点,它向我展示了如何确保任何功能都可以存在。然后我想进一步确保有一个带有特定参数的函数存在。我首先定义类型T必须有一个返回int的函数号

#include <concepts>

template <typename T>
concept MyRequirement = requires (T t) 
{
    { t.number(int) } -> std::same_as<int>;
};

template <typename T>
  requires MyRequirement<T>
struct RequiresBool
{
  T t;
};

struct GoodType
{
    int number(int x) { return x; };
};

int main() 
{
    RequiresBool<GoodType> good_object;
}

但是整数/双数让我头疼


使用C++20概念是否可以确保MyRequirement中的x类型必须是整数?

我还不太熟悉这些概念,因此可能有一种更惯用的方法。但这对我来说很直观,而且很有效

#include <type_traits>

template <typename T>
concept MyRequirement = std::is_same_v<decltype(&T::number), int (T::*)(int)>;
这包括返回类型和参数

如果不熟悉,int T::*int是指向成员函数的指针,其签名int属于类T。
decltype&T::number获取指向Ts成员编号的指针的类型。

我还不熟悉这些概念,因此可能有一种更惯用的方法。但这对我来说很直观,而且很有效

#include <type_traits>

template <typename T>
concept MyRequirement = std::is_same_v<decltype(&T::number), int (T::*)(int)>;
这包括返回类型和参数

如果不熟悉,int T::*int是指向成员函数的指针,其签名int属于类T。 decltype&T::number获取指向Ts成员编号的指针的类型。

复合要求{expression}检查表达式是否格式正确,因此会发生隐式类型转换。int可以隐式转换为double,但std::string不能隐式转换为int

您可以在复合需求中使用指向成员的指针:

template <typename T>
concept MyRequirement = requires {
    { &T::number } -> std::same_as<int (T::*)(int)>;
};
复合需求{expression}检查表达式是否格式正确,因此会发生隐式类型转换。int可以隐式转换为double,但std::string不能隐式转换为int

您可以在复合需求中使用指向成员的指针:

template <typename T>
concept MyRequirement = requires {
    { &T::number } -> std::same_as<int (T::*)(int)>;
};

是否需要&in&T::number,因为它引用函数对象,并且需要将其与返回类型中指定的函数指针进行比较?T::number&T::number是指向成员函数的指针,是少数允许id表达式表示类的非静态数据成员或非静态成员函数的上下文之一。是否需要&in&T::number,因为它引用函数对象,并且需要将其与返回类型中指定的函数指针进行比较?T::number&number是一个指向成员函数的指针,是少数允许使用id表达式表示类的非静态数据成员或非静态成员函数的上下文之一。
template <typename T>
concept MyRequirement = requires {
    { &T::number } -> std::same_as<int (T::*)(int)>;
};