Nice programing

후행 반환 유형 구문 스타일이 새로운 C ++ 11 프로그램의 기본값이되어야합니까?

nicepro 2020. 10. 11. 11:20
반응형

후행 반환 유형 구문 스타일이 새로운 C ++ 11 프로그램의 기본값이되어야합니까?


C ++ 11은 새로운 함수 구문을 지원합니다.

auto func_name(int x, int y) -> int;

현재이 함수는 다음과 같이 선언됩니다.

int func_name(int x, int y);

새로운 스타일은 아직 널리 채택되지 않은 것 같습니다 (예 : gcc stl)

그러나이 새로운 스타일은 새로운 C ++ 11 프로그램의 모든 곳에서 선호되어야합니까, 아니면 필요할 때만 사용됩니까?

개인적으로 저는 가능하면 예전 스타일을 선호하지만, 스타일이 혼합 된 코드 기반은 꽤보기 흉해 보입니다.


후행 반환 유형을 사용해야하는 특정 경우가 있습니다. 특히 람다 반환 유형이 지정된 경우 후행 반환 유형을 통해 지정되어야합니다. 또한 반환 유형 decltype이 인수 이름이 범위 내에 있어야하는를 사용하는 경우 후행 반환 유형을 사용해야합니다 (그러나 일반적 declval<T>으로이 문제를 해결 하는 사용할 수 있음 ).

후행 반환 유형에는 몇 가지 다른 사소한 이점이 있습니다. 예를 들어, 전통적인 함수 구문을 사용하는 비 인라인 멤버 함수 정의를 고려하십시오.

struct my_awesome_type
{
    typedef std::vector<int> integer_sequence;

    integer_sequence get_integers() const;
}; 

my_awesome_type::integer_sequence my_awesome_type::get_integers() const
{
    // ...
}

멤버 typedef는 클래스 이름이 앞에 나타날 때까지 범위에 포함되지 않으므로 ::get_integers클래스 제한을 두 번 반복해야합니다. 후행 반환 유형을 사용하는 경우 유형의 이름을 반복 할 필요가 없습니다.

auto my_awesome_type::get_integers() const -> integer_sequence
{
    // ...
}

이 예제에서는 그렇게 큰 문제는 아니지만 인라인으로 정의되지 않은 클래스 템플릿의 멤버 함수 나 긴 클래스 이름이 있으면 가독성에 큰 차이를 만들 수 있습니다.

자신의에서 "신선한 페인트" C ++ 이제 2012 세션, 엘리스 데어 메레디스는 지속적으로 반환 형식을 후행 사용하는 경우, 당신의 모든 기능의 이름이 깔끔하게 정렬 지적 :

auto foo() -> int;
auto bar() -> really_long_typedef_name;

나는 도처에 반환 형식을 후행 사용했습니다 CxxReflect 당신이 코드 외모가 일관되게 사용하는 방법의 예를 찾고 그렇다면, 당신은보고있다 (예를 들어,이 걸릴 수 클래스 ).type


다른 사람들이 말한 것 외에도 후행 반환 유형은를 사용할 this수 있습니다.

struct A {
  std::vector<int> a;

  // OK, works as expected
  auto begin() const -> decltype(a.begin()) { return a.begin(); }

  // FAIL, does not work: "decltype(a.end())" will be "iterator", but 
  // the return statement returns "const_iterator"
  decltype(a.end()) end() const { return a.end(); }
};

두 번째 선언에서는 전통적인 스타일을 사용했습니다. 그러나 this해당 위치에서는 허용되지 않으므로 컴파일러에서 암시 적으로 사용하지 않습니다. 따라서는 a.end()정적으로 선언 된 유형을 사용하여 호출 할 오버로드 a를 결정하고 이는 상수가 아닌 버전이됩니다.endvector<int>


또 다른 장점은 함수가 함수에 대한 포인터를 반환 할 때 후행 반환 유형 구문을 더 쉽게 읽을 수 있다는 것입니다. 예를 들어, 비교

void (*get_func_on(int i))(int);

auto get_func_on(int i) -> void (*)(int);

그러나 함수 포인터에 대한 유형 별칭을 도입하는 것만으로 더 나은 가독성을 얻을 수 있다고 주장 할 수 있습니다.

using FuncPtr = void (*)(int);
FuncPtr get_func_on(int i);

이 멋진 기사를 참조하십시오 : http://www.cprogramming.com/c++11/c++11-auto-decltype-return-value-after-function.html 게임에서 decltype없이이 구문을 사용할 때 아주 좋은 예 :

class Person
{
public:
    enum PersonType { ADULT, CHILD, SENIOR };
    void setPersonType (PersonType person_type);
    PersonType getPersonType ();
private:
    PersonType _person_type;
};

auto Person::getPersonType () -> PersonType
{
    return _person_type;
}

그리고 Alex Allain의 기사에서 "반환 값이 함수 이전이 아니라 함수의 끝으로 가기 때문에 클래스 범위를 추가 할 필요가 없습니다."에서 빼낸 멋진 설명도 있습니다.

우연히 클래스 범위를 잊어 버리고 더 큰 재난의 경우 다른 PersonType이 전역 범위에 정의 된이 가능한 경우와 비교하십시오.

typedef float PersonType; // just for even more trouble
/*missing: Person::*/
PersonType Person::getPersonType ()
{
    return _person_type;
}

참고URL : https://stackoverflow.com/questions/11215227/should-the-trailing-return-type-syntax-style-become-the-default-for-new-c11-pr

반응형