수색…
비고
2014 년 11 월 C ++ 표준위원회는 직접 초기화 구문을 사용하여 자동 및 브레이스 이니셜 라이저에 대한 특수 유형 공제 규칙을 제거하는 제안 N3922를 채택했습니다. 이것은 C ++ 표준의 일부가 아니지만 일부 컴파일러에 의해 구현되었습니다.
생성자에 대한 템플릿 매개 변수 공제
C ++ 17 이전에는 템플릿 추론이 생성자에서 클래스 유형을 추론 할 수 없습니다. 명시 적으로 지정해야합니다. 그러나 때로는 이러한 유형이 매우 복잡하거나 (람다의 경우) 이름 지정이 불가능하기 때문에 make_pair()
, make_tuple()
, back_inserter()
등과 같은 유형 팩토리가 확산되었습니다.
더 이상 필요하지 않습니다.
std::pair p(2, 4.5); // std::pair<int, double>
std::tuple t(4, 3, 2.5); // std::tuple<int, int, double>
std::copy_n(vi1.begin(), 3,
std::back_insert_iterator(vi2)); // constructs a back_insert_iterator<std::vector<int>>
std::lock_guard lk(mtx); // std::lock_guard<decltype(mtx)>
생성자는 클래스 템플릿 매개 변수를 추론하는 것으로 간주되지만 일부 경우에는 충분하지 않으며 명시 적 공제 안내를 제공 할 수 있습니다.
template <class Iter>
vector(Iter, Iter) -> vector<typename iterator_traits<Iter>::value_type>
int array[] = {1, 2, 3};
std::vector v(std::begin(array), std::end(array)); // deduces std::vector<int>
템플릿 유형 공제
템플릿 일반 구문
template<typename T>
void f(ParamType param);
f(expr);
사례 1 : ParamType
은 참조 또는 포인터이지만 범용 또는 순방향 참조는 아닙니다. 이 경우 유형 공제는 이런 식으로 작동합니다. 컴파일러는 참조 부분이 expr
있으면 무시합니다. 그런 다음 컴파일러는 expr
의 형식을 ParamType
과 패턴 일치 ParamType
T
를 결정합니다.
template<typename T>
void f(T& param); //param is a reference
int x = 27; // x is an int
const int cx = x; // cx is a const int
const int& rx = x; // rx is a reference to x as a const int
f(x); // T is int, param's type is int&
f(cx); // T is const int, param's type is const int&
f(rx); // T is const int, param's type is const int&
사례 2 : ParamType
은 범용 참조 또는 전달 참조입니다. 이 경우 expr
이 rvalue 인 경우 유형 공제는 사례 1과 동일합니다. expr
이 lvalue 인 경우, T
와 ParamType
은 모두 좌변 값 참조로 추론됩니다.
template<typename T>
void f(T&& param); // param is a universal reference
int x = 27; // x is an int
const int cx = x; // cx is a const int
const int& rx = x; // rx is a reference to x as a const int
f(x); // x is lvalue, so T is int&, param's type is also int&
f(cx); // cx is lvalue, so T is const int&, param's type is also const int&
f(rx); // rx is lvalue, so T is const int&, param's type is also const int&
f(27); // 27 is rvalue, so T is int, param's type is therefore int&&
사례 3 : ParamType
이 포인터도 참조도 아닙니다. expr
이 참조 인 경우 참조 부분은 무시됩니다. expr
이 const 인 경우는 무시됩니다. 휘발성 인 경우 T의 유형을 추론 할 때 무시됩니다.
template<typename T>
void f(T param); // param is now passed by value
int x = 27; // x is an int
const int cx = x; // cx is a const int
const int& rx = x; // rx is a reference to x as a const int
f(x); // T's and param's types are both int
f(cx); // T's and param's types are again both int
f(rx); // T's and param's types are still both int
자동 유형 공제
auto
키워드를 사용하는 유형 공제는 템플릿 유형 공제와 거의 동일합니다. 다음은 몇 가지 예입니다.
auto x = 27; // (x is neither a pointer nor a reference), x's type is int
const auto cx = x; // (cx is neither a pointer nor a reference), cs's type is const int
const auto& rx = x; // (rx is a non-universal reference), rx's type is a reference to a const int
auto&& uref1 = x; // x is int and lvalue, so uref1's type is int&
auto&& uref2 = cx; // cx is const int and lvalue, so uref2's type is const int &
auto&& uref3 = 27; // 27 is an int and rvalue, so uref3's type is int&&
차이점은 아래에 요약되어 있습니다.
auto x1 = 27; // type is int, value is 27
auto x2(27); // type is int, value is 27
auto x3 = { 27 }; // type is std::initializer_list<int>, value is { 27 }
auto x4{ 27 }; // type is std::initializer_list<int>, value is { 27 }
// in some compilers type may be deduced as an int with a
// value of 27. See remarks for more information.
auto x5 = { 1, 2.0 } // error! can't deduce T for std::initializer_list<t>
braced initializer를 사용하면 알 수 있듯이 auto는 std::initializer_list<T>
유형의 변수를 만들도록 강제됩니다. T
추론 할 수 없으면 코드는 거부됩니다.
auto
가 함수의 반환 유형으로 사용되면 함수에 후행 반환 유형이 지정 됩니다.
auto f() -> int {
return 42;
}
C ++ 14에서는 C ++ 11에서 자동 허용의 사용 외에도 다음을 허용합니다.
후행 반환 형식이없는 함수의 반환 형식으로 사용되는 경우 함수의 반환 형식이 함수 본문의 반환 문에서 추론되어야한다고 지정합니다 (있는 경우).
// f returns int: auto f() { return 42; } // g returns void: auto g() { std::cout << "hello, world!\n"; }
람다의 매개 변수 유형에 사용되면 람다를 일반 람다 로 정의합니다.
auto triple = [](auto x) { return 3*x; }; const auto x = triple(42); // x is a const int with value 126
특수 형식 decltype(auto)
은 auto
대신 decltype
의 형식 공제 규칙을 사용하여 형식을 추론합니다.
int* p = new int(42);
auto x = *p; // x has type int
decltype(auto) y = *p; // y is a reference to *p
C ++ 03 이전 버전에서 auto
키워드는 C에서 상속 된 저장소 클래스 지정자 와 완전히 다른 의미를가집니다.