C++类型推导与auto关键字
C++类型推导与auto关键字
类型推导是C++11引入的重要特性,通过auto和decltype关键字,编译器可以自动推导变量的类型,减少代码冗余并提高可维护性。
auto关键字让编译器根据初始化表达式推导变量类型。
#include
#include
#include
#include
void basic_auto_usage() {
auto x = 42;
auto y = 3.14;
auto z = "hello";
std::cout << "x type: int, value: " << x << "\n";
std::cout << "y type: double, value: " << y << "\n";
std::cout << "z type: const char*, value: " << z << "\n";
auto vec = std::vector{1, 2, 3, 4, 5};
std::cout << "Vector size: " << vec.size() << "\n";
}
auto在迭代器使用中特别有用,避免了冗长的类型声明。
void auto_with_iterators() {
std::map scores = {
{"Alice", 95},
{"Bob", 87},
{"Charlie", 92}
};
for (auto it = scores.begin(); it != scores.end(); ++it) {
std::cout << it->first << ": " << it->second << "\n";
}
for (const auto& pair : scores) {
std::cout << pair.first << ": " << pair.second << "\n";
}
}
auto推导时会去除引用和const限定符,需要显式添加。
void auto_qualifiers() {
int x = 42;
const int& ref = x;
auto a = ref;
auto& b = ref;
const auto& c = ref;
a = 100;
std::cout << "x after modifying a: " << x << "\n";
std::cout << "Type of a: int (copy)\n";
std::cout << "Type of b: const int& (reference)\n";
std::cout << "Type of c: const int& (const reference)\n";
}
decltype用于查询表达式的类型,不会对表达式求值。
void decltype_basic() {
int x = 42;
decltype(x) y = 100;
std::cout << "y: " << y << "\n";
const int& ref = x;
decltype(ref) z = x;
std::cout << "Type of z preserves const and reference\n";
}
decltype(auto)结合了auto和decltype的特性,保留表达式的完整类型信息。
template
decltype(auto) access(Container& c, Index i) {
return c[i];
}
void decltype_auto_example() {
std::vector vec = {1, 2, 3, 4, 5};
decltype(auto) value = access(vec, 2);
value = 100;
std::cout << "Modified vector[2]: " << vec[2] << "\n";
}
auto可以用于函数返回类型推导。
auto add(int a, int b) {
return a + b;
}
auto multiply(double a, double b) -> decltype(a * b) {
return a * b;
}
template
auto generic_add(T a, U b) -> decltype(a + b) {
return a + b;
}
void auto_return_type() {
std::cout << "add(3, 4): " << add(3, 4) << "\n";
std::cout << "multiply(2.5, 3.0): " << multiply(2.5, 3.0) << "\n";
std::cout << "generic_add(10, 3.5): " << generic_add(10, 3.5) << "\n";
}
auto在lambda表达式中简化了类型声明。
void auto_with_lambda() {
auto lambda = [](int x, int y) {
return x + y;
};
std::cout << "Lambda result: " << lambda(10, 20) << "\n";
auto generic_lambda = [](auto a, auto b) {
return a + b;
};
std::cout << "Generic lambda (int): " << generic_lambda(5, 10) << "\n";
std::cout << "Generic lambda (double): " << generic_lambda(2.5, 3.5) << "\n";
}
结构化绑定使用auto解包复合类型。
#include
std::tuple get_data() {
return {42, 3.14, "hello"};
}
void structured_bindings() {
auto [x, y, z] = get_data();
std::cout << "x: " << x << ", y: " << y << ", z: " << z << "\n";
std::map scores = {{"Alice", 95}, {"Bob", 87}};
for (const auto& [name, score] : scores) {
std::cout << name << ": " << score << "\n";
}
std::pair p = {1, "one"};
auto& [id, text] = p;
id = 2;
std::cout << "Modified pair: " << p.first << ", " << p.second << "\n";
}
auto可以用于模板参数推导。
template
struct Constant {
static constexpr auto value = Value;
};
void template_auto() {
Constant<42> int_const;
Constant<3.14> double_const;
std::cout << "Int constant: " << int_const.value << "\n";
std::cout << "Double constant: " << double_const.value << "\n";
}
类型推导在复杂表达式中特别有用。
void complex_type_deduction() {
std::vector>> complex_data;
complex_data.push_back({
{"numbers", {1, 2, 3}},
{"more", {4, 5, 6}}
});
for (const auto& map : complex_data) {
for (const auto& [key, vec] : map) {
std::cout << key << ": ";
for (auto val : vec) {
std::cout << val << " ";
}
std::cout << "\n";
}
}
}
auto不能用于函数参数,但可以用于泛型lambda。
void auto_limitations() {
auto lambda = [](auto x) {
return x * 2;
};
std::cout << "Lambda with int: " << lambda(21) << "\n";
std::cout << "Lambda with double: " << lambda(3.14) << "\n";
}
类型推导与完美转发结合使用。
template
auto forward_wrapper(T&& arg) {
return std::forward(arg);
}
void type_deduction_forwarding() {
int x = 42;
auto result1 = forward_wrapper(x);
auto result2 = forward_wrapper(100);
std::cout << "Forwarded lvalue: " << result1 << "\n";
std::cout << "Forwarded rvalue: " << result2 << "\n";
}
类型推导是现代C++的重要特性,它使代码更简洁、更易维护,同时保持类型安全。
