수색…


비고

2014 년 11 월 C ++ 표준위원회는 직접 초기화 구문을 사용하여 자동 및 브레이스 이니셜 라이저에 대한 특수 유형 공제 규칙을 제거하는 제안 N3922를 채택했습니다. 이것은 C ++ 표준의 일부가 아니지만 일부 컴파일러에 의해 구현되었습니다.

생성자에 대한 템플릿 매개 변수 공제

C ++ 17 이전에는 템플릿 추론이 생성자에서 클래스 유형을 추론 할 수 없습니다. 명시 적으로 지정해야합니다. 그러나 때로는 이러한 유형이 매우 복잡하거나 (람다의 경우) 이름 지정이 불가능하기 때문에 make_pair() , make_tuple() , back_inserter() 등과 같은 유형 팩토리가 확산되었습니다.

C ++ 17

더 이상 필요하지 않습니다.

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 인 경우, TParamType 은 모두 좌변 값 참조로 추론됩니다.

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

자동 유형 공제

C ++ 11

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 ++ 14에서는 C ++ 11에서 자동 허용의 사용 외에도 다음을 허용합니다.

  1. 후행 반환 형식이없는 함수의 반환 형식으로 사용되는 경우 함수의 반환 형식이 함수 본문의 반환 문에서 추론되어야한다고 지정합니다 (있는 경우).

    // f returns int:
    auto f() { return 42; }
    // g returns void:
    auto g() { std::cout << "hello, world!\n"; }
    
  2. 람다의 매개 변수 유형에 사용되면 람다를 일반 람다 로 정의합니다.

    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에서 상속 된 저장소 클래스 지정자 와 완전히 다른 의미를가집니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow