C++11의 새로운 기능에서 auto와 decltype의 차이점과 연관성
1. auto 소개
프로그래밍할 때 비용을 지불해야 하는 경우가 많습니다. 변수에 대한 표현식 값은 다음에서 수행되어야 합니다. 변수를 선언할 때 해당 변수가 어떤 유형인지 정확히 알 수 있습니다. 그러나 이를 수행하는 것은 쉽지 않으며(특히 템플릿의 경우) 전혀 불가능할 때도 있습니다. 이 문제를 해결하기 위해 새로운 C++11 표준에는 자동 유형 지정자가 도입되었습니다. 이를 통해 컴파일러는 표현식 유형을 분석할 수 있습니다. 이는 특정 유형 지정자(예: int)에만 해당하는 원래 것과 다릅니다. auto를 사용하면 컴파일러가 초기 값을 통해 유형 추론을 수행할 수 있습니다. 이렇게 해서 정의된 변수의 타입을 구하게 되므로 auto로 정의한 변수는 초기값을 가지고 있어야 합니다.
//由val_1 和val_2相加的结果可以推断出item的类型 auto item = val_1 + val_2;//item 类型初始化为val_1 + val_2相加后的类型,值为val_1+val_2相加的值。
여기서 항목 유형은 컴파일 프로세스 중에 val_1 및 val_2 유형을 추가하여 컴파일러에 의해 계산됩니다. val_1(int) + val_2(double)이면 항목의 유형이 double이므로 우비의 모든 변수의 초기 기본 데이터 유형이 동일해야 합니다. 여기서는 데이터 유형과 유형 수정자를 구별해야 합니다! !
int i = 3; auto a = i,&b = i,*c = &i;//正确: a初始化为i的副本,b初始化为i的引用,c为i的指针. auto sz = 0, pi = 3.14;//错误,两个变量的类型不一样。컴파일러가 유추한 자동 유형이 초기 값의 유형과 정확히 동일하지 않은 경우가 있습니다. 컴파일러는 초기화와 더 일관되도록 결과 유형을 적절하게 변경합니다. 규칙.
우선 우리 모두 알고 있듯이 참조를 사용하는 것은 실제로 참조의 객체를 사용하는 것입니다. 특히 참조를 초기값으로 사용할 때 실제로 초기화에 참여하는 것은 의 값입니다. 참조 객체. 이때 컴파일러는 참조 객체의 유형을 auto의 유형으로 사용합니다.
int i = 0 ,&r = i;//定义一个整数i,并且定义r为i的应用. auto a = r; //这里的a为为一个整数,其值跟此时的i一样.auto는 참조를 무시한다는 것을 알 수 있습니다. 둘째, auto는 일반적으로 참조를 무시합니다. 최상위 const는 유지되지만 초기 값이 상수에 대한 포인터인 경우와 같이 최하위 const는 유지됩니다.
int i = 0; const int ci = i, &cr = ci; //ci 为整数常量,cr 为整数常量引用 auto a = ci; // a 为一个整数, 顶层const被忽略 auto b = cr; // b 为一个整数,顶层const被忽略 auto c = &ci; // c 为一个整数指针. auto d = &cr; // d 为一个指向整数常量的指针(对常量对象区地址是那么const会变成底层const)auto 유형을 추론하려는 경우 최상위 const이므로 명시적으로 지적해야 합니다.
const auto f = ci;참조 유형을 auto로 설정할 수도 있습니다. 이 경우 원래 초기화 규칙이 계속 적용됩니다(const 사용됨). 참조 선언은 모두 기본 const입니다):
auto &g = ci; //g是一个整数常量引用,绑定到ci。 auto &h = 42; // 错误:非常量引用的初始值必须为左值。 const auto &j = 42; //正确:常量引用可以绑定到字面值。2. decltype 소개 때때로 우리는 변수의 유형을 추론하고 싶을 때가 있습니다. 표현식에서 정의되지만 표현식 값을 사용하여 변수를 초기화하고 싶지는 않습니다. 함수의 반환 유형이 표현식의 값 유형일 수도 있습니다. 이 경우 auto는 무력하므로 C++11에서는 피연산자의 데이터 유형을 선택하고 반환하는 데 사용되는 두 번째 유형 지정자 decltype을 도입합니다. 이 프로세스 동안 컴파일러는 표현식을 분석하고 해당 유형만 가져오지만 실제로 표현식의 값을 계산하지는 않습니다.
decltype(f()) sum = x;// sum的类型就是函数f的返回值类型。여기서 컴파일러는 실제로 f 함수를 호출하지 않지만 f 함수의 반환 값을 정의된 sum 유형으로 분석합니다.
기본적으로 decltype의 기능은 auto의 기능과 매우 유사하므로 하나씩 나열하지는 않겠습니다. decltype의 또 다른 용도는 C++11에 도입된 접미사 반환 유형입니다.
const int ci = 42, &cj = ci; decltype(ci) x = 0; // x 类型为const int auto z = ci; // z 类型为int decltype(cj) y = x; // y 类型为const int& auto h = cj; // h 类型为intdecltype에 관해 주목할 만한 몇 가지 사항이 있습니다. 먼저 다음 코드를 살펴보겠습니다.
int i = 42, *p = &i, &r = i; decltype(i) x1 = 0; //因为 i 为 int ,所以 x1 为int auto x2 = i; //因为 i 为 int ,所以 x2 为int decltype(r) y1 = i; //因为 r 为 int& ,所以 y1 为int& auto y2 = r; //因为 r 为 int& ,但auto会忽略引用,所以 y2 为int decltype(r + 0) z1 = 0; //因为 r + 0 为 int ,所以 z1 为int, auto z2 = r + 0; //因为 r + 0 为 int ,所以 z2 为int, decltype(*p) h1 = i; //这里 h1 是int&, 原因后面讲 auto h2 = *p; // h2 为 int.표현식의 내용이 역참조 연산인 경우 decltype은 참조 유형을 가져옵니다. . 우리가 잘 알고 있듯이 포인터를 역참조하면 포인터가 가리키는 개체를 얻을 수 있으며 이 개체에 값을 할당할 수도 있습니다. 따라서 decltype(*p)의 결과 유형은 int&입니다.
decltype과 auto의 또 다른 중요한 차이점은 decltype의 결과 유형이 표현식 형식과 밀접한 관련이 있다는 것입니다. 특별한 주의가 필요한 상황이 하나 있습니다. decltype에서 사용하는 표현식의 경우 변수 이름에 괄호 쌍을 추가하면 얻은 유형이 괄호가 없는 유형과 다를 수 있습니다. decltype이 괄호 없이 변수를 사용하는 경우 결과는 변수 유형입니다. 그러나 이 변수에 하나 이상의 괄호 레이어를 추가하면 컴파일러는 이 변수를 표현식으로 처리합니다. 변수는 lvalue로 사용할 수 있는 특수 표현식이므로 이러한 decltype은 참조 유형을 반환합니다.
으르르르
这里再指出一个需要注意的地方就是 = 赋值运算符返回的是左值的引用。换句话意思就是说 decltype(i = b) 返回类型为 i 类型的引用。仔细看下面这段代码:
int main() { int i = 42; decltype(i = 41) x = i; auto y = i; auto& z = i; printf("i x y z 此时为: %d %d %d %d\n", i,x,y,z); i--; printf("i x y z 此时为: %d %d %d %d\n", i, x, y, z); x--; printf("i x y z 此时为: %d %d %d %d\n", i, x, y, z); y--; printf("i x y z 此时为: %d %d %d %d\n", i, x, y, z); z--; printf("i x y z 此时为: %d %d %d %d\n", i, x, y, z); return 0; }
运行结果为:
i x y z 此时为: 42 42 42 42 i x y z 此时为: 41 41 42 41 i x y z 此时为: 40 40 42 40 i x y z 此时为: 40 40 41 40 i x y z 此时为: 39 39 41 39
由上面的代码和运行结果可以看出来,1.decltype(i = 41)中的赋值语句并没有真正的运行。2. decltype(i = 41)返回的其实是int&,也就是说x 其实是 i 的引用。
了解了auto 和 decltype后,以后在使用的过程中一定要分清两者的区别,防止在定义的时候产生const 与非const 以及引用 与非引用 的差别!!
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
更多C++11新特性中auto 和 decltype 区别和联系相关文章请关注PHP中文网!