编译运行:clang++ -std=c++26 -Wall -Wextra -pthread 测试_第10章_模板与泛型.cpp -o t && ./t(需先 cd 测试/)
// 第10章测试:模板与泛型
#include <print>
#include <string>
#include <type_traits>
#include <concepts>
int failures = 0;
#define CHECK(expr) \
do { \
if (!(expr)) { \
++failures; \
std::println("FAIL 第{}行: {}", __LINE__, #expr); \
} \
} while (0)
// 10.1 函数模板
template <typename T>
T max_of(T a, T b) { return a > b ? a : b; }
// 10.3 类模板
template <typename T>
class Box {
public:
explicit Box(T value) : value_(std::move(value)) {}
const T& get() const { return value_; }
private:
T value_;
};
// 10.4 if constexpr + type traits
template <typename T>
std::string what_kind(const T& v) {
if constexpr (std::is_pointer_v<T>) {
return "指针:" + std::to_string(*v);
} else if constexpr (std::is_same_v<T, std::string>) {
return "字符串:" + v;
} else if constexpr (std::is_integral_v<T>) {
return "整数:" + std::to_string(v);
} else {
return "其他";
}
}
// 10.5 变参模板 + 折叠表达式
template <typename... Ts>
auto sum_all(Ts... args) { return (args + ...); }
template <typename... Ts>
int count_all(Ts... args) { return sizeof...(args); }
// 10.7 concepts
template <std::integral T>
T double_it(T x) { return x * 2; }
template <typename T>
concept HasArea = requires(const T& t) {
{ t.area() } -> std::same_as<double>;
};
template <HasArea T>
double total_area(const T& t) { return t.area(); }
int main() {
// 10.1
CHECK(max_of(3, 7) == 7);
CHECK(max_of(3.5, 2.1) == 3.5);
CHECK(max_of(std::string("b"), std::string("a")) == "b");
// 10.3
Box<int> b1(42);
Box<std::string> b2("hi");
CHECK(b1.get() == 42);
CHECK(b2.get() == "hi");
// 10.4
int iv = 5;
int* pv = &iv;
std::string sv = "text";
CHECK(what_kind(pv) == "指针:5");
CHECK(what_kind(sv) == "字符串:text");
CHECK(what_kind(iv) == "整数:5");
// 10.5 折叠
CHECK(sum_all(1, 2, 3, 4) == 10);
CHECK(sum_all(1.5, 2.5) == 4.0);
CHECK(sum_all(std::string("a"), std::string("b"), std::string("c")) == "abc");
CHECK(count_all(1, 2.5, "x") == 3);
// 10.7 concepts
CHECK(double_it(21) == 42);
// double_it(3.5); // 编译错误:double 不是 integral
struct Square { double area() const { return 4.0; } };
Square sq;
CHECK(total_area(sq) == 4.0);
// 10.6 编译期类型检查
static_assert(std::is_integral_v<int>);
static_assert(!std::is_integral_v<double>);
static_assert(std::is_pointer_v<int*>);
using Plain = std::remove_const_t<const int>;
static_assert(std::is_same_v<Plain, int>);
if (failures == 0) std::println("全部通过");
return failures;
}