在C 编程中,模板是一种强大的工具,可以实现代码的通用性和复用性。然而,传统的模板编程经常需要显式指定模板参数,这可能会导致代码重复和可读性下降。为了解决这个问题,C 17引入了CTAD(Class Template Argument Deduction,类模板参数推导)特性,它使得在实例化类模板时可以省略模板参数的显式指定,由编译器根据构造函数参数的类型推导出模板参数。
例如C 17之前,如果使用std::vector需要指定参数类型,但是C 17以后便不需要了。
代码语言:javascript复制std::vector<int> vec_before{ 1, 2, 3, 4, 5 }; //before c 17
auto vec_after= std::vector{ 1, 2, 3, 4, 5 };
简介
CTAD(Class Template Argument Deduction,类模板参数推导),顾名思义,类模板的参数无需显示指定转而由编译器自动推导,即允许在实例化类模板时省略模板参数的显式指定,由编译器根据构造函数参数的类型推导出模板参数。这种推导机制不仅简化代码,还可以提高代码的可读性和可维护性,其好处可以分为如下几个方面:
- 简洁性:CTAD允许我们在实例化类模板时省略模板参数的显式指定,使得代码更加简洁清晰。
- 安全性:CTAD在类型推导过程中保证了类型安全,确保了程序的正确性。
- 可读性:CTAD提高了代码的可读性,使得代码更易于理解和维护。
代码示例
代码语言:javascript复制#include <iostream>
#include <vector>
#include <array>
void using_ctad()
{
auto vec = std::vector{ 1, 2, 3, 4, 5 }; //-> std::vector<int>
auto arr = std::array{ 1, 2, 3, 4, 5 }; //-> std::array<int, 5>
auto p = std::pair{ 1, 2 }; //-> std::pair<int, int>
auto t = std::tuple{ 1, 2, 3 }; //-> std::tuple<int, int, int>
auto ptr = std::make_unique {"Hello, CTAD!"}; //-> std::unique_ptr<std::string>
// 输出示例
std::cout << "Vector: ";
for (auto& elem : vec) {
std::cout << elem << " ";
}
std::cout << std::endl;
std::cout << "Array: ";
for (auto& elem : arr) {
std::cout << elem << " ";
}
std::cout << std::endl;
std::cout << "Pair: (" << p.first << ", " << p.second << ")" << std::endl;
std::cout << "Tuple: (" << std::get<0>(t) << ", " << std::get<1>(t) << ", " << std::get<2>(t) << ")" << std::endl;
}
在上面的示例中,我们使用CTAD分别实例化了std::vector、std::array、std::pair和std::tuple,并输出了它们的内容。
结论
CTAD它允许在实例化类模板时省略模板参数的显式指定,由编译器根据构造函数参数的类型推导出模板参数。不仅简化了代码,而且提高了代码的可读性和可维护性。其适用于所有需要实例化类模板的场景,特别适用于使用STL容器、智能指针等类模板的情况。