<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;} // namespaceint 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;
}
执行结果如下图所示:
GitHub:https://github.com/fengbingchun/Messy_Test