自学内容网 自学内容网

C++20中头文件concepts的使用

      <concepts>是C++20中新增加的头文件,此头文件是concepts库的一部分,主要用于模板编程、泛型编程。包括

      1.core language concepts:

      std::same_as:指定一种类型(type)与另一种类型是否相同。

      std::derived_from:指定一种类型是否派生自另一种类型。

      std::convertible_to:指定一种类型是否可以隐式转换为另一种类型。

      std::common_reference_with:指定两种类型是否共享一个公共的引用类型。

      std::common_with:指定两种类型是否共享一个公共类型。

      std::integral:指定类型是否为整数类型。

      std::signed_integral:指定类型是否为有符号的整数类型。

      std::unsigned_integral:指定类型是否为无符号的整数类型。

      std::floating_point:指定类型是否为浮点类型。

      std::assignable_from:指定一种类型是否可以从另一种类型分配。

      std::swappable、std::swappable_with:指定类型是否可以交换。

      std::destructible:指定该类型的对象是否可以被销毁。

      std::default_initializable:指定类型的对象是否可以默认构造。

      std::move_constructible:指定类型的对象是否可以进行移动构造。

      std::copy_constructible:指定类型的对象可以被拷贝构造和移动构造。

namespace {

struct A{
int x, y;

//A(int x,int y):x(x), y(y) {}

bool operator==(const A& other) const
{
return x == other.x && y == other.y;
}

//bool operator!=(const A& other) const
//{
//return !(*this == other);
//}
};

struct B{
int x, y;

auto operator<=>(const B& other) const = default;
auto operator()() const
{
return x % 2 == 0;
}
};

struct C : public A{
C(C&&) = delete;
C& operator=(C&&) = delete;
};

struct D : private A{
int x, y;

D() = delete;

auto operator()() 
{
return (x + y);
}
};

using INT = int;
using FLOAT = float;

} // namespace

int test_concepts_core_lanuage()
{
static_assert(std::same_as<A, B> == false, "A and B are not the same"); // std::is_same_v<T, U>
static_assert(std::derived_from<C, A> == true);
static_assert(std::derived_from<A, C> == false);
static_assert(!std::derived_from<D, A>);
static_assert(std::convertible_to<C, A>);
static_assert(std::common_reference_with<C, A>);
static_assert(std::common_with<C, A>);

static_assert(std::integral<INT>);
static_assert(!std::integral<FLOAT>);
static_assert(std::signed_integral<INT>);
static_assert(!std::unsigned_integral<INT>);
static_assert(std::floating_point<FLOAT>);

static_assert(std::assignable_from<std::string&, std::string>);
static_assert(!std::assignable_from<std::string, std::string>);
static_assert(!std::assignable_from<std::string, std::string&>);

static_assert(std::default_initializable<A>);
static_assert(std::move_constructible<B>);
static_assert(std::copy_constructible<D>);

return 0;
}

      2.comparison concepts:

      std::equality_comparable,std::equality_comparable_with:用于检查指定类型是否支持==运算符。

      std::totally_ordered,std::totally_ordered_with:用于检查指定类型是否支持所有比较操作符。

int test_concepts_comparison()
{
static_assert(std::equality_comparable<A>);
static_assert(std::equality_comparable<B>);
static_assert(std::equality_comparable<C>);

static_assert(!std::totally_ordered<A>);
static_assert(std::totally_ordered<B>);

return 0;
}

      3.object concepts:

      std::movable:指定类型的对象是否可以进行移动构造和swapped。

      std::copyable:指定类型的对象是否可以进行拷贝、移动和swapped。

      std::semiregular:指定类型的对象是否可以进行拷贝、移动、swapped和默认构造。

      std::regular:指定类型是否是regular的,即:

template<class T>
concept regular = std::semiregular<T> && std::equality_comparable<T>;
int test_concepts_object()
{
static_assert(std::movable<A>);
static_assert(std::movable<B>);
static_assert(!std::movable<C>);

static_assert(std::copyable<A>);
static_assert(std::copyable<B>);
static_assert(!std::copyable<C>);

static_assert(std::semiregular<A>);
static_assert(!std::semiregular<D>);

static_assert(std::regular<A>);
static_assert(!std::regular<D>);

return 0;
}

      4.callable concepts:

      std::invocable、std::regular_invocable:检查给定的可调用对象是否可以被调用,即是否含有operator()。

      std::predicate:指定可调用类型是否是布尔谓词(boolean predicate)。

      std::relation:指定可调用类型是否是二元关系(binary relation)。

int test_concepts_callable()
{
static_assert(!std::regular_invocable<A>);
static_assert(std::regular_invocable<D>);

static_assert(!std::predicate<A>);
static_assert(std::predicate<B>);

static_assert(!std::relation<A, B, C>);


return 0;
}

      5.customization point objects:

      std::ranges::swap:交换两个对象的值。

int test_concepts_customization_point_objects()
{
int x{ 1 }, y{ -1 };
std::cout << "x=" << x << ", y=" << y << std::endl;
std::ranges::swap(x, y);
std::cout << "x=" << x << ", y=" << y << std::endl;

std::string addr1{ "TianJin" }, addr2{ "BeiJing" };
std::cout << "addr1=" << addr1 << ", addr2=" << addr2 << std::endl;
std::ranges::swap(addr1, addr2);
std::cout << "addr1=" << addr1 << ", addr2=" << addr2 << std::endl;

auto print = [](const std::vector<int>& vec) {
for (const auto& value : vec)
std::cout << value << ",";
std::cout << std::endl;
};

std::vector vec1{ 1, 2, 3 }, vec2{ -1,-2,-3,-4,-5 };
std::cout << "vec1: "; print(vec1);
std::cout << "vec2: "; print(vec2);
std::ranges::swap(vec1, vec2);
std::cout << "vec1: "; print(vec1);
std::cout << "vec2: "; print(vec2);

return 0;
}

      执行结果如下图所示:

      GitHubhttps://github.com/fengbingchun/Messy_Test


原文地址:https://blog.csdn.net/fengbingchun/article/details/142618418

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!