수색…


비고

키워드 auto 는 자동 추론 된 유형을 나타내는 typename입니다.

C에서 상속 된 C ++ 98에서는 이미 예약어였습니다. 이전 버전의 C ++에서는 변수에 자동 저장 기간이 있음을 명시하는 데 사용할 수있었습니다.

int main()
{
  auto int i = 5; // removing auto has no effect
}

그 옛 의미가 제거되었습니다.

기본 자동 샘플

키워드 auto 는 변수 유형의 자동 공제를 제공합니다.

긴 타입의 이름을 다룰 때 특히 편리합니다 :

std::map< std::string, std::shared_ptr< Widget > > table;
// C++98
std::map< std::string, std::shared_ptr< Widget > >::iterator i = table.find( "42" );
// C++11/14/17
auto j = table.find( "42" );

범위 기반 for 루프 :

vector<int> v = {0, 1, 2, 3, 4, 5};
for(auto n: v)
    std::cout << n << ' ';

람다 와 함께 :

auto f = [](){ std::cout << "lambda\n"; };
f();        

유형의 반복을 피하기 위해 :

auto w = std::make_shared< Widget >();

놀랍고 불필요한 사본을 피하려면

auto myMap = std::map<int,float>();
myMap.emplace(1,3.14);

std::pair<int,float> const& firstPair2 = *myMap.begin();  // copy!
auto const& firstPair = *myMap.begin();  // no copy!

복사본의 이유는 반환 된 유형이 실제로 std::pair<const int,float> !

자동 및 표현식 템플릿

auto 는 또한 표현 템플릿이 작동하는 문제를 일으킬 수 있습니다.

auto mult(int c) {
    return c * std::valarray<int>{1};
}

auto v = mult(3);
std::cout << v[0]; // some value that could be, but almost certainly is not, 3.

그 이유는, 즉 operator*valarray 당신에게 지칭 프록시 객체 부여 valarray 지연 평가 수단으로한다. auto 을 사용하면 매달려있는 참조가 생성됩니다. mult 대신 std::valarray<int> 반환 std::valarray<int> 코드는 확실히 3을 인쇄합니다.

자동, const 및 참조

auto 키워드 자체는 int 또는 char 과 비슷한 값 유형을 나타냅니다. const 키워드 및 & 기호로 수정하여 각각 const 유형 또는 참조 유형을 나타낼 수 있습니다. 이 수정자는 결합 될 수 있습니다.

이 예제에서 s 는 값 유형 (유형이 std::string 으로 유추 됨)이므로 for 루프의 각 반복은 벡터에서 s 로 문자열을 복사 합니다.

std::vector<std::string> strings = { "stuff", "things", "misc" };
for(auto s : strings) {
    std::cout << s << std::endl;
}

루프의 본문이 s.append(" and stuff") 등)를 호출하여 s 수정하면 원래의 strings 구성원이 아닌이 복사본 만 수정 strings .

반면에 sauto& 로 선언되면 참조 유형 ( std::string& 유추 됨)이되므로 루프의 각 반복마다 벡터의 문자열에 대한 참조 가 할당됩니다.

for(auto& s : strings) {
    std::cout << s << std::endl;
}

이 루프의 본문에서 s 를 수정하면 참조하는 strings 요소에 직접 영향을줍니다.

마지막으로, sconst auto& 로 선언되면 const 참조 유형이됩니다. 즉, 루프의 각 반복에 벡터의 문자열에 대한 const 참조 가 할당됩니다.

for(const auto& s : strings) {
    std::cout << s << std::endl;
}

이 루프 본문에서 s 는 수정할 수 없습니다 (즉, const가 아닌 메소드를 호출 할 수 없음).

범위 기반 for 루프와 함께 auto 를 사용할 때 불필요한 복사본을 피하기 때문에 루프 본문이 반복되는 구조를 수정하지 않으면 일반적으로 const auto& 를 사용하는 것이 좋습니다.

후행 반환 유형

auto 는 후행 형식의 구문에 사용됩니다.

auto main() -> int {}

이는

int main() {}

주로 std::declval<T> 대신에 매개 변수를 사용하는 decltype 과 결합하면 유용합니다.

template <typename T1, typename T2>
auto Add(const T1& lhs, const T2& rhs) -> decltype(lhs + rhs) { return lhs + rhs; }

일반 람다 (C ++ 14)

C ++ 14

C ++ 14에서는 lambda 인수에서 auto 를 사용할 수 있습니다.

auto print = [](const auto& arg) { std::cout << arg << std::endl; };

print(42);
print("hello world");

그 람다는

struct lambda {
    template <typename T>
    auto operator ()(const T& arg) const {
        std::cout << arg << std::endl;
    }
};

그리고

lambda print;

print(42);
print("hello world");

자동 및 프록시 개체

때때로 auto 는 프로그래머가 예상했던대로 작동하지 않을 수도 있습니다. 유형 공제가 옳지 않은 경우에도 유형은 표현식을 추론합니다.

예를 들어 프록시 객체가 코드에서 사용될 때 :

std::vector<bool> flags{true, true, false};
auto flag = flags[0];
flags.push_back(true);

flagbool 이 아니지만 std::vector<bool>::reference 입니다. 템플릿 vectorbool 특수화의 경우 operator [] 는 변환 연산자 operator bool 정의 된 프록시 객체를 반환합니다.

flags.push_back(true) 가 컨테이너를 수정하면이 의사 참조는 더 이상 존재하지 않는 요소를 참조하여 flags.push_back(true) 될 수 있습니다.

또한 다음 상황을 가능하게합니다.

void foo(bool b);

std::vector<bool> getFlags();

auto flag = getFlags()[5];
foo(flag);

vector 는 즉시 폐기되므로 flag 는 삭제 된 요소에 대한 의사 참조입니다. foo 호출하면 정의되지 않은 동작이 호출됩니다.

이와 같은 경우 auto 으로 변수를 선언하고 추론 할 유형으로 변환하여 초기화 할 수 있습니다.

auto flag = static_cast<bool>(getFlags()[5]);

그러나 그 시점에서 단순히 boolauto 로 바꾸는 것이 더 합리적입니다.

프록시 객체가 문제를 일으킬 수있는 또 다른 경우는 표현 템플릿 입니다. 이 경우, 템플릿은 때로는 효율성을 위해 현재의 전체 표현식을 넘어 서도록 설계되지 않고 다음에 프록시 객체를 사용하면 정의되지 않은 동작이 발생합니다.



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