C ++ 03에서 ‘auto’키워드를 사용하는 이유가 있습니까? 질문에 C ++ (11)이 비준되기

참고 이 질문에 C ++ (11)이 비준되기 전에 원래 2009에 게시했습니다과의 의미 전에 auto키워드 대폭 변경되었습니다. 제공된 답변 은 자동 유형 추론 의 C ++ 11 의미가 아니라 지정된 스토리지 클래스 라는 C ++ 03 의미 에만 관련 됩니다 . C ++ 11 사용시기에 대한 조언을 찾고 있다면 이 질문은 해당 질문과 관련이 없습니다.autoautoauto

오랫동안 staticC 에서 키워드 를 사용할 이유가 없다고 생각했습니다. 블록 범위 밖에서 선언 된 변수는 암시 적으로 전역 적이기 때문입니다. 그런 다음 static블록 범위 내 에서 변수를 선언 하면 영구 기간이 제공되고 블록 범위 외부 (프로그램 범위 내에서)로 선언하면 파일 범위가 제공된다는 것을 발견했습니다 (해당 컴파일 단위에서만 액세스 할 수 있음).

그래서 이것은 내가 (아마도) 아직 완전히 이해하지 못하는 하나의 키워드만을 남깁니다. 바로 auto키워드입니다. ‘로컬 변수’외에 다른 의미가 있습니까? 어디에서 사용하든 암묵적으로 수행되지 않는 작업이 있습니까? auto변수는 프로그램 범위에서 어떻게 작동합니까? static auto파일 범위 의 변수는 무엇입니까 ? 이 키워드는 완전성을 위해 존재 하는 것 외에 다른 목적을 가지고 있습니까?



답변

auto스토리지 클래스 지정자입니다, static, registerextern도. 선언에서이 네 가지 중 하나만 사용할 수 있습니다.

로컬 변수 (가없는 static)는 자동 저장 기간을 가지며, 이는 정의 시작부터 블록 끝까지 존재 함을 의미합니다. 어쨌든 기본값이기 때문에 자동을 앞에 두는 것은 중복됩니다.

C ++에서 사용하는 이유를 모르겠습니다. 암시 적 int 규칙이있는 이전 C 버전에서는 다음과 같이이를 사용하여 변수를 선언 할 수 있습니다.

int main(void) { auto i = 1; }

유효한 구문으로 만들거나 case i가 범위 내에있는 경우 할당 식에서 명확하게하기 위해 . 그러나 이것은 어쨌든 C ++에서 작동하지 않습니다 (유형을 지정해야합니다). 재미있게도 C ++ 표준은 다음과 같이 씁니다.

블록 범위에서 스토리지 클래스 지정자없이 선언되거나 함수 매개 변수로 선언 된 객체는 기본적으로 자동 저장 기간을 갖습니다. [참고 : 따라서 자동 지정자는 거의 항상 중복되며 자주 사용되지 않습니다. auto의 한 가지 용도는 선언문을 표현 문 (6.8)과 명시 적으로 구별하는 것입니다. — 끝 참고]

그 중 캐스팅이 될 수있는 다음과 같은 시나리오를 의미 a하는 int나 변수의 선언 a유형의 int주위에 여분의 괄호를 가지고 a. 항상 선언으로 간주되므로 auto여기에 유용한 정보를 추가하지 않고 대신 인간을위한 것입니다. 그러나 다시 말하지만, 인간은 주위의 중복 괄호를 제거하는 것이 더 나을 a것입니다.

int(a);

autoC ++ 0x와 함께 도착 하는 새로운 의미로 인해 코드에서 C ++ 03의 의미와 함께 사용하지 않는 것이 좋습니다.


답변

C ++ 11에서 auto새로운 의미가 있습니다. 변수의 유형을 자동으로 추론 할 수 있습니다.

그게 왜 유용할까요? 기본적인 예를 살펴 보겠습니다.

std::list<int> a;
// fill in a
for (auto it = a.begin(); it != a.end(); ++it) {
  // Do stuff here
}

auto타입의 반복자가 만들어집니다 std::list<int>::iterator.

이렇게하면 심각하게 복잡한 코드를 훨씬 쉽게 읽을 수 있습니다.

또 다른 예:

int x, y;
auto f = [&]{ x += y; };
f();
f();

거기에서 auto람다 식을 변수에 저장하는 데 필요한 유형을 추론했습니다. Wikipedia는 주제에 대해다루고 있습니다.


답변

auto 키워드는 현재 아무런 목적이 없습니다. 지역 변수의 기본 스토리지 클래스를 다시 작성하는 것이 맞습니다 static. 정말 유용한 대안은 .

그것은 C ++ 0x에서 새로운 의미 를 가지고 있습니다. 그것은 당신에게 그것이 얼마나 쓸모 없는지에 대한 몇 가지 아이디어를 제공합니다!


답변

GCC는 auto중첩 함수 에 대한 특수 용도를 가지고 있습니다 . 여기를 참조 하십시오 .

정의하기 전에 호출하려는 중첩 함수가있는 경우 auto.


답변

“auto”는 컴파일러에게 변수 (메모리 또는 레지스터)를 넣을 위치를 스스로 결정하도록 지시합니다. 그것의 아날로그는 “레지스터”인데, 이것은 컴파일러에게 레지스터에 그것을 유지하도록 지시하는 것으로 추정됩니다. 현대 컴파일러는 둘 다 무시하므로 여러분도 그렇게해야합니다.


답변

이 키워드를 사용하여 함수에 중요한시기, 스택 기반 프로세서의 경우 변수가 스택에 배치되는 경우를 명시 적으로 문서화합니다. 이 함수는 함수 (또는 인터럽트 서비스 루틴)에서 복귀하기 전에 스택을 수정할 때 필요할 수 있습니다. 이 경우 다음을 선언합니다.

auto unsigned int auiStack[1];   //variable must be on stack

그런 다음 변수 외부에 액세스합니다.

#define OFFSET_TO_RETURN_ADDRESS 8     //depends on compiler operation and current automatics
auiStack[OFFSET_TO_RETURN_ADDRESS] = alternate_return_address;

따라서 auto키워드는 의도를 문서화하는 데 도움이됩니다.


답변

Stroustrup에 따르면 “The C Programming Language”(4 판, C 11 포함)에서 ‘auto’를 사용하는 데는 다음과 같은 주요 이유가 있습니다 (섹션 2.2.2) (Stroustrup 단어가 인용 됨).

1)

정의는 우리가 코드를 읽는 사람이 유형을 명확하게 볼 수 있도록하는 넓은 범위에 있습니다.

‘auto’와 필요한 이니셜 라이저를 사용하면 변수의 유형을 한 눈에 알 수 있습니다!

2)

변수의 범위 또는 정밀도에 대해 명시하고 싶습니다 (예 : float가 아닌 double).

제 생각에 여기에 맞는 경우는 다음과 같습니다.

   double square(double d)
    {
        return d*d;
    }

    int square(int d)
    {
        return d*d;
    }

    auto a1 = square(3);

    cout << a1 << endl;

    a1 = square(3.3);

    cout << a1 << endl;

삼)

‘auto’를 사용하여 중복성을 피하고 긴 유형 이름을 작성합니다.

템플릿 화 된 반복자의 긴 형식 이름을 상상해보십시오.

(섹션 6.3.6.1의 코드)

template<class T> void f1(vector<T>& arg) {
    for (typename vector<T>::iterator p = arg.begin(); p != arg.end();   p)
        *p = 7;

    for (auto p = arg.begin(); p != arg.end();   p)
        *p = 7;
}