다음을 통해 공유


auto(C++)

초기화 식에서 선언된 변수의 형식을 추론합니다.

참고 항목

C++ 표준에는 이 키워드의 원래 의미와 수정된 의미가 정의되어 있습니다. Visual Studio 2010 전까지 auto 키워드에서는 자동 스토리지 클래스에 있는 변수, 즉 현지 수명이 있는 변수를 선언합니다. Visual Studio 2010부터 auto 키워드에서는 선언의 초기화 식에서 형식이 추론되는 변수를 선언합니다. /Zc:auto[-] 컴파일러 옵션은 auto 키워드의 의미를 제어합니다.

구문

auto declaratorinitializer;

[](auto param1, autoparam2) {};

설명

auto 키워드는 선언된 변수 또는 람다 식 매개 변수의 초기화 식을 사용하여 해당 형식을 추론하도록 컴파일러에 지시합니다.

auto 키워드는 다음과 같은 이점을 제공하므로 꼭 변환이 필요한 경우가 아니라면 대부분의 경우 이 키워드를 사용하는 것이 좋습니다.

  • 강력함: 함수의 반환 형식이 변경할 때 포함되므로 식의 형식이 변경되는 경우에도 작동합니다.

  • 성능: 변환이 없음을 보증합니다.

  • 유용성: 형식 이름 맞춤법 문제 및 오타를 걱정할 필요가 없습니다.

  • 효율성: 코딩의 효율성이 향상됩니다.

auto을 사용하지 않는 변환의 경우:

  • 특정 형식을 원한다면, 다른 항목은 사용할 수 없습니다.

  • 언어 식 템플릿 도우미 유형 - (예: (valarray+valarray)).

auto 키워드를 사용하려면 형식 대신 이를 사용하여 변수를 선언하고 초기화 식을 지정합니다. 또한 지정자 및 auto, const, 포인터(volatile), 참조(*) 및 rvalue 참조(&)를 사용하여 && 키워드를 수정할 수 있습니다. 컴파일러는 초기화 식을 계산하고 해당 정보를 사용하여 변수의 형식을 추론합니다.

auto 초기화 식은 다음과 같이 여러 가지 형식을 취할 수 있습니다.

  • 유니버설 초기화 구문(예: auto a { 42 };).
  • 대입 구문(예: auto b = 0;).
  • 유니버설 할당 구문(예: auto c = { 3.14159 };, 두 개의 이전 형식을 결합함).
  • 직접 초기화 또는 생성자 스타일 구문(예: auto d( 1.41421f );).

자세한 내용은 이니셜라이저 및 이 문서의 뒷부분에 있는 코드 예제를 참조하세요.

auto이 범위 기반 for 문에서 루프 매개 변수를 선언하는 데 사용되는 경우, 다른 초기화 구문을 사용합니다(예: for (auto& i : iterable) do_action(i);). 자세한 내용은 범위 기반 for 문(C++)을 참조하세요.

auto 키워드는 형식 그 자체가 아니라 형식을 위한 자리 표시자입니다. 따라서 auto 키워드는 sizeof 및 (C++/CLI용) typeid과 같은 캐스트 또는 연산자에서 사용할 수 없습니다.

유용성

auto 키워드는 복잡한 형식의 변수를 선언하는 간단한 방법입니다. 예를 들어 auto을 사용하여 초기화 식이 템플릿, 함수에 대한 포인터 또는 멤버에 대한 포인터와 관련된 변수를 선언할 수 있습니다.

auto을 사용하여 변수를 람다 식으로 선언 및 초기화할 수 있습니다. 람다 식의 형식은 컴파일러에만 알려져 있기 때문에 직접 변수 유형을 선언할 수 없습니다. 자세한 내용은 람다 식의 예제를 참조하세요.

후행 반환 형식

autodecltype 형식 지정자와 함께 사용하여 템플릿 라이브러리를 작성할 수 있습니다. 반환 형식이 템플릿 인수 형식에 따라 달라지는 함수 템플릿을 선언하려면 autodecltype를 사용합니다. 또는 다른 함수에 대한 호출을 래핑한 후 다른 함수의 반환 형식을 반환하는 템플릿 함수를 선언하려면 autodecltype를 사용합니다. 자세한 내용은 decltype를 참조하세요.

참조 및 cv 한정자

auto 드롭 참조, const 한정자 및 volatile 한정자를 사용하세요. 다음 예제를 참조하세요.

// cl.exe /analyze /EHsc /W4
#include <iostream>

using namespace std;

int main( )
{
    int count = 10;
    int& countRef = count;
    auto myAuto = countRef;

    countRef = 11;
    cout << count << " ";

    myAuto = 12;
    cout << count << endl;
}

이전 예제에서 myAuto는 int이지 int 참조가 아니므로 출력은 11 11이며, 11 12로 인해 참조 한정자가 드롭되었을 경우처럼 auto가 아닙니다.

중괄호로 묶인 이니셜라이저를 사용한 형식 추론(C++14)

다음 코드 예제에서는 중괄호를 사용하여 auto 변수를 초기화하는 방법을 보여줍니다. B와 C의 차이점과 A와 E의 차이점을 잘 살펴보세요.

#include <initializer_list>

int main()
{
    // std::initializer_list<int>
    auto A = { 1, 2 };

    // std::initializer_list<int>
    auto B = { 3 };

    // int
    auto C{ 4 };

    // C3535: cannot deduce type for 'auto' from initializer list'
    auto D = { 5, 6.7 };

    // C3518 in a direct-list-initialization context the type for 'auto'
    // can only be deduced from a single initializer expression
    auto E{ 8, 9 };

    return 0;
}

제한 사항 및 오류 메시지

다음 표에서는 auto 키워드 사용에 대한 제한 사항 및 컴파일러에서 내보내는 해당 진단 오류 메시지를 보여줍니다.

오류 번호 설명
C3530 auto 키워드는 다른 형식 지정자와 함께 사용할 수 없습니다.
C3531 auto 키워드를 사용하여 선언된 기호에는 이니셜라이저가 있어야 합니다.
C3532 auto 키워드를 잘못 사용하여 형식을 선언했습니다. 예를 들어 메서드 반환 형식 또는 배열을 선언했습니다.
C3533, C3539 매개 변수 또는 템플릿 인수는 auto 키워드를 사용하여 선언할 수 없습니다.
C3535 메서드 또는 템플릿 매개 변수는 auto 키워드를 사용하여 선언할 수 없습니다.
C3536 초기화되기 전에는 기호를 사용할 수 없습니다. 실제로는 변수를 사용하여 자신을 초기화할 수 없음을 의미합니다.
C3537 auto 키워드를 사용하여 선언된 형식으로 캐스팅할 수 없습니다.
C3538 auto 키워드를 사용하여 선언된 선언자 목록의 모든 기호는 동일한 형식으로 확인되어야 합니다. 자세한 내용은 선언 및 정의를 참조하세요.
C3540, C3541 키워드를 사용하여 선언된 기호에 sizeofauto 연산자를 적용할 수 없습니다.

예제

이러한 코드 조각은 auto 키워드를 사용할 수 있는 몇 가지 방법을 보여줍니다.

다음 선언은 동일합니다. 첫 번째 문에서는 j 변수가 int 형식으로 선언되었습니다. 두 번째 문에는 초기화 식(0)이 정수이므로 k 변수가 int 형식으로 추론되었습니다.

int j = 0;  // Variable j is explicitly type int.
auto k = 0; // Variable k is implicitly type int because 0 is an integer.

다음 선언은 동일하지만 두 번째 선언이 첫 번째 선언보다 간단합니다. auto 키워드를 사용하는 가장 중요한 이유 중 하나는 단순성입니다.

map<int,list<string>>::iterator i = m.begin();
auto i = m.begin();

다음 코드 조각은 iter 및 범위 elem 루프가 시작될 때 forfor 형식의 변수를 선언합니다.

// cl /EHsc /nologo /W4
#include <deque>
using namespace std;

int main()
{
    deque<double> dqDoubleData(10, 0.1);

    for (auto iter = dqDoubleData.begin(); iter != dqDoubleData.end(); ++iter)
    { /* ... */ }

    // prefer range-for loops with the following information in mind
    // (this applies to any range-for with auto, not just deque)

    for (auto elem : dqDoubleData) // COPIES elements, not much better than the previous examples
    { /* ... */ }

    for (auto& elem : dqDoubleData) // observes and/or modifies elements IN-PLACE
    { /* ... */ }

    for (const auto& elem : dqDoubleData) // observes elements IN-PLACE
    { /* ... */ }
}

다음 코드 조각에서는 new 연산자 및 포인터 선언을 사용하여 포인터를 선언합니다.

double x = 12.34;
auto *y = new auto(x), **z = new auto(&x);

다음 코드 조각은 각 선언문에서 여러 기호를 선언합니다. 각 명령문의 모든 기호는 동일한 형식으로 확인됩니다.

auto x = 1, *y = &x, **z = &y; // Resolves to int.
auto a(2.01), *b (&a);         // Resolves to double.
auto c = 'a', *d(&c);          // Resolves to char.
auto m = 1, &n = m;            // Resolves to int.

다음 코드 조각은 조건부 연산자(?:)를 사용하여 변수 x를 정수 값을 200 값을 갖는 정수로 선언합니다.

int v1 = 100, v2 = 200;
auto x = v1 > v2 ? v1 : v2;

다음 코드 조각에서는 x 변수를 int 형식으로 초기화하고, y 변수를 const int 형식에 대한 참조로 초기화하고, fp 변수를 int 형식을 반환하는 함수에 대한 포인터로 초기화합니다.

int f(int x) { return x; }
int main()
{
    auto x = f(0);
    const auto& y = f(1);
    int (*p)(int x);
    p = f;
    auto fp = p;
    //...
}

참고 항목

키워드
/Zc:auto(Deduce 변수 형식)
sizeof 연산자
typeid
operator new
선언 및 정의
람다 식의 예제
Initializers
decltype