C++11新特性_第二章_通用性增强_返回值后置类型后置,范围for,nullptr,lambda
本文记录C++11的返回值类型后置,范围for,nullptr, lambda表达式。
第二章 通用性增强
2.3 返回值类型后置 (追踪返回类型)
在不使用返回值后置的情况下,返回值类型需要手工指定。T和U根据实参可自动推导,在程序中可以不写。
template<typename R,typename T,typename U>
R add(T t, U u)
{
return t + u;
}
void test()
{
int x = 321;
double y = 2.2;
auto z = add<double, int, double>(x, y);
cout << "z = " << z << endl;
// z = 323.2
auto z2 = add<decltype(x + y)>(x, y);
cout << "z2 = " << z2 << endl;
// z = 323.2
}
使用返回类型后置,可以减少一个参数:
template<typename T, typename U>
auto add3(T t, U u)-> decltype(t + u) // 这种方式不可,因为t + u还未定义
{
return t + u;
}
void test2()
{
int x = 321;
double y = 2.2;
auto z = add3<int, double>(x, y);
cout << "z = " << z << endl;
// z = 323.2
auto z2 = add3(x, y);
cout << "z2 = " << z2 << endl;
// z = 323.2
}
2.4 范围for
C++11 引入了范围for循环,书写方便。
void test()
{
// 迭代器的循环
vector<int> vec{ 3,4,5,6 };
for (vector<int>::iterator it = vec.begin(); it != vec.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
// 使用auto
for (auto it = vec.begin(); it != vec.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
// 范围for : value是 vec中复制,可以使用引用
for (auto value : vec)
{
cout << value << " ";
}
cout << endl;
// 使用引用,可以修改 vec , 如果不修改,加上const,表示只读
for (const auto& value : vec)
{
cout << value << " ";
}
// 3 4 5 6
}
2.5 指针空值类型 nullptr(类型转换运算符)
C++11之前都是NULL对指针初始化。 NULL实现原理如下:
#ifndef NULL
#ifdef __cplusplus // 如果源码是C++程序,NULL 是0
#define NULL 0
#else
#define NULL ((void *)0) // 其他如果是C程序,对0进行 void*转换为指针
#endif
#endif
为何这样转呢?因为C++中,void 类型无法隐士转换为其他类型指针,此时使用0代替(void)0;在C中可以自动转换。这个 0 表示进程的虚拟地址空间为 0的地址,这个地址是保留区,这个区域是只读的,没有实际的物理内存映射,因此任何对它的引用都是非法的。但是这种做法在C++中在函数重载的场景下是有问题的,比如函数重载时,NULL 和 0 无法区分。
void func(int* p)
{
cout << "void func(int* p)" << endl;
}
void func(int p)
{
cout << "void func(int p)" << endl;
}
void test2()
{
func(nullptr);
// void func(int* p)
func(NULL); // 想要调用 func(int* p)
// void func(int p)
int* p = NULL;
func(p);
// void func(int* p)
// 因为C++中NULL 就是0。
}
为了解决这个问题,C++11引入了nullptr,专门用于初始化空类型指针,不同类型指针都可使用nullptr初始化。
void test3()
{
int* p1 = nullptr;
double* p2 = nullptr;
void* p3 = nullptr;
}
nullptr实现原理探究:概念性的实现(实际由编译器处理),使用C++类实现如下:
重载了类型转换运算符,使用一个模板 + T (),这个实现operator前边没有返回值,但是在operator前边不允许指定返回值类型,比如:T operator T*() const { return 0; },这是错误的。
class nullptr_t_impl
{
public:
// 类型转换操作符重载
template<typename T>
operator T* () const
{
return 0;
}
// 可以转换为任何成员指针类型
template<typename T, typename U>
operator T U::* () const
{
return 0;
}
// 不允许转换为其他类型
template<typename T>
operator T() const = delete;
private:
// 阻止取地址
void operator&() const = delete;
};
// 全局常量
const nullptr_t_impl nullptr1 = {};
// 主要测试函数
void test()
{
cout << "=== nullptr_t_impl 测试用例 ===" << endl;
// 测试1: 基本指针类型转换
cout << "\n1. 测试指针类型转换:" << endl;
int* p_int = nullptr1; // 编译器内部:nullptr1.operator int*()
double* p_double = nullptr1;
char* p_char = nullptr1;
void* p_void = nullptr1;
cout << "int* p_int = nullptr1; -> " << p_int << endl;
cout << "double* p_double = nullptr1; -> " << p_double << endl;
cout << "char* p_char = nullptr1; -> " << p_char << endl;
cout << "void* p_void = nullptr1; -> " << p_void << endl;
}
类似的,凡是类型转换运算符,都不需要有返回值,比如int类型转换运算符,double,bool等类型转换,都是直接operator + 类型(),不需要指定返回值,但是实现时,需要返回指定的类型,实现如下:
class ConversionExample
{
public:
int value;
ConversionExample(int v) : value(v) {}
// 转换为 int
operator int() const
{
cout << "调用 operator int()" << endl;
return value;
}
// 转换为 double
operator double() const {
cout << "调用 operator double()" << endl;
return static_cast<double>(value);
}
// 转换为 bool
operator bool() const {
cout << "调用 operator bool()" << endl;
return value != 0;
}
// 转换为字符串指针
operator const char* () const {
cout << "调用 operator const char*()" << endl;
return value > 0 ? "positive" : "zero or negative";
}
};
void test()
{
cout << "\n=== 转换操作符类型演示 ===" << endl;
ConversionExample obj(42);
// 各种隐式转换
int i = obj; // 调用 operator int()
double d = obj; // 调用 operator double()
bool b = obj; // 调用 operator bool()
const char* s = obj; // 调用 operator const char*()
cout << "int i = " << i << endl;
cout << "double d = " << d << endl;
cout << "bool b = " << b << endl;
cout << "const char* s = " << s << endl;
}
2.6 lambda表达式
lambda表达式是C++11引入的一个利器,这部分内容在下面这篇文章中进行了详细说明,链接如下:
C++_chapter15_C++重要知识点_lambda,initializer_list
更多推荐
所有评论(0)