约束 class 模板函数以接受特定的 POD 类型
Constraining class template function to accept a specific POD type
我正在自学 C++20 的新概念功能,但在尝试确保必须存在的成员函数只接受特定类型时遇到了障碍。我发现 向我展示了如何确保任何功能都可以存在。然后我想通过确保存在具有特定参数的函数来更进一步。我首先定义 T
类型必须有一个 number()
函数 returns 一个 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;
}
但是 gcc 给了我以下错误:
<source>:7:16: error: expected primary-expression before 'int'
7 | { t.number(int) } -> std::same_as<int>;
| ^~~"
所以我将其更改为以下有效。
template <typename T>
concept MyRequirement = requires (T t, int x)
{
{ t.number(x) } -> std::same_as<int>;
};
然而,当我将 GoodType
中的函数签名更改为 int number(double x)
时,它仍然有效。当然,double
可以隐式转换为 int
,这也适用于普通函数。我可以通过在 GoodType
中声明(但不定义)int number(double);
来解决这个问题,这会在编译期间给我一个错误,但这让编写模板 class 的人有责任记住这样做。
这适用于其他类型,例如
template <typename T>
concept MyRequirement = requires (T t, std::string x)
{
{ t.number(x) } -> std::same_as<int>; //int number(int x) is now invalid
};
但是integers/doubles让我很头疼。
是否有某种方法确保 MyRequirement
中 x 的类型必须是使用 C++20 概念的整数?
我还不熟悉概念,所以可能有更惯用的方法。但这对我来说很直观并且有效。
#include <type_traits>
template <typename T>
concept MyRequirement = std::is_same_v<decltype(&T::number), int (T::*)(int)>;
这包括 return 类型和参数。
如果不熟悉,int (T::*)(int)
是一个指向成员函数的指针,其签名 int(int)
属于 class T
.
decltype(&T::number)
获取指向 T
成员 number
的指针的类型。
复合要求 ({ expression}
) 检查表达式是否格式正确,因此会发生隐式类型转换。 int
可以隐式转换为 double
,但 std::string
不能隐式转换为 int
.
您可以在复合要求中使用指向成员的指针:
template <typename T>
concept MyRequirement = requires {
{ &T::number } -> std::same_as<int (T::*)(int)>;
};
我正在自学 C++20 的新概念功能,但在尝试确保必须存在的成员函数只接受特定类型时遇到了障碍。我发现 T
类型必须有一个 number()
函数 returns 一个 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;
}
但是 gcc 给了我以下错误:
<source>:7:16: error: expected primary-expression before 'int'
7 | { t.number(int) } -> std::same_as<int>;
| ^~~"
所以我将其更改为以下有效。
template <typename T>
concept MyRequirement = requires (T t, int x)
{
{ t.number(x) } -> std::same_as<int>;
};
然而,当我将 GoodType
中的函数签名更改为 int number(double x)
时,它仍然有效。当然,double
可以隐式转换为 int
,这也适用于普通函数。我可以通过在 GoodType
中声明(但不定义)int number(double);
来解决这个问题,这会在编译期间给我一个错误,但这让编写模板 class 的人有责任记住这样做。
这适用于其他类型,例如
template <typename T>
concept MyRequirement = requires (T t, std::string x)
{
{ t.number(x) } -> std::same_as<int>; //int number(int x) is now invalid
};
但是integers/doubles让我很头疼。
是否有某种方法确保 MyRequirement
中 x 的类型必须是使用 C++20 概念的整数?
我还不熟悉概念,所以可能有更惯用的方法。但这对我来说很直观并且有效。
#include <type_traits>
template <typename T>
concept MyRequirement = std::is_same_v<decltype(&T::number), int (T::*)(int)>;
这包括 return 类型和参数。
如果不熟悉,int (T::*)(int)
是一个指向成员函数的指针,其签名 int(int)
属于 class T
.
decltype(&T::number)
获取指向 T
成员 number
的指针的类型。
复合要求 ({ expression}
) 检查表达式是否格式正确,因此会发生隐式类型转换。 int
可以隐式转换为 double
,但 std::string
不能隐式转换为 int
.
您可以在复合要求中使用指向成员的指针:
template <typename T>
concept MyRequirement = requires {
{ &T::number } -> std::same_as<int (T::*)(int)>;
};