std :: initializer_list가 기본 제공 언어가 아닌 이유는 무엇입니까?
std::initializer_list
핵심 언어가 기본으로 제공 되지 않는 이유는 무엇 입니까?
C ++ 11의 매우 중요한 기능이지만 자체 예약 된 키워드 (또는 유사)가없는 것 같습니다.
대신, initializer_list
그건 단지 특별한 암시가 표준 라이브러리에서 템플릿 클래스 매핑 새로운에서 보강-초기화리스트 {...}
컴파일러에 의해 처리하는 것 구문을.
처음에이 솔루션은 상당히 엉망 입니다.
이것이 C ++ 언어에 대한 새로운 추가가 이제 구현되는 방식 입니까? 핵심 언어가 아닌 일부 템플릿 클래스의 암시 적 역할 에 의해 구현 됩니까?
다음 예를 고려하십시오.
widget<int> w = {1,2,3}; //this is how we want to use a class
왜 새로운 클래스가 선택 되었습니까?
widget( std::initializer_list<T> init )
다음 아이디어 와 유사한 것을 사용하는 대신 :
widget( T[] init, int length ) // (1)
widget( T... init ) // (2)
widget( std::vector<T> init ) // (3)
const
여기저기서 추가 할 수 있습니다.- 언어에 이미 세 개의 점이 존재합니다 (var-args, 이제 가변 템플릿), 구문을 재사용하지 않는 이유 (그리고 내장 된 것처럼 느끼게 함 )
- 기존 컨테이너 만 추가
const
하고&
그들 모두는 이미 언어의 일부입니다. 나는 첫 번째 아이디어를 세 개만 썼고 다른 많은 접근 방식 이 있다고 확신합니다 .
std
네임 스페이스에 정의 된 유형을 반환하는 "핵심"언어 기능의 예가 이미있었습니다 . typeid
반환 std::type_info
하고 (아마도 점을 늘리면)를 sizeof
반환합니다 std::size_t
.
전자의 경우 소위 "핵심 언어"기능을 사용하려면 이미 표준 헤더를 포함해야합니다.
이제 이니셜 라이저 목록의 경우 객체를 생성하는 데 키워드가 필요하지 않으며 구문은 상황에 맞는 중괄호입니다. 그 외에는 type_info
. 개인적으로 나는 키워드의 부재가 그것을 "더 해키"하게 만든다고 생각하지 않습니다. 약간 더 놀랍지 만, 목표는 이미 집계에 허용 된 것과 동일한 중괄호 이니셜 라이저 구문을 허용하는 것이 었습니다.
그렇습니다. 앞으로이 디자인 원칙을 더 많이 기대할 수 있습니다.
- 새로운 키워드없이 새로운 기능을 도입 할 수있는 경우가 더 많이 발생하면위원회에서이를 채택합니다.
- 새로운 기능에 복잡한 유형이 필요한 경우 해당 유형은
std
내장이 아닌에 배치됩니다 .
그 후:
- 새 기능에 복잡한 유형이 필요하고 새 키워드없이 도입 할 수있는 경우 여기에있는 것을 얻을 수 있습니다. 이는 새 키워드가없는 "핵심 언어"구문이며에서 라이브러리 유형을 사용합니다
std
.
내 생각에는 C ++에서 "핵심 언어"와 표준 라이브러리 사이에 절대적인 구분이 없다고 생각합니다. 그것들은 표준의 다른 장이지만 각각은 다른 장을 참조하며 항상 그렇습니다.
C ++ 11에는 람다 가 컴파일러에 의해 생성 된 익명 형식 을 가진 개체를 도입하는 또 다른 접근 방식이 있습니다 . 이름이 없기 때문에 네임 스페이스에 전혀없고 std
. 하지만 이니셜 라이저 목록에는 적합한 접근 방식이 아닙니다. 하나를 허용하는 생성자를 작성할 때 유형 이름을 사용하기 때문입니다.
C ++ 표준위원회는 새 키워드를 추가하지 않는 것을 선호하는 것 같습니다. 이는 기존 코드를 손상시킬 위험을 증가시키기 때문일 것입니다 (레거시 코드는 해당 키워드를 변수, 클래스 또는 다른 이름으로 사용할 수 있음).
또한 std::initializer_list
템플릿 컨테이너로 정의하는 것은 매우 우아한 선택 인 것 같습니다. 키워드라면 기본 유형에 어떻게 액세스할까요? 어떻게 반복 하시겠습니까? 새로운 연산자도 많이 필요하며, 표준 컨테이너로 할 수있는 것과 동일한 작업을 수행하기 위해 더 많은 이름과 키워드를 기억해야합니다.
를 std::initializer_list
다른 컨테이너와 같이 취급하면 이러한 것들과 함께 작동하는 일반 코드를 작성할 수 있습니다.
최신 정보:
그렇다면 기존의 조합을 사용하는 대신 새로운 유형을 도입하는 이유는 무엇입니까? (댓글에서)
우선 다른 모든 컨테이너에는 요소를 추가, 제거 및 대체하는 메서드가 있으며 이는 컴파일러 생성 컬렉션에는 바람직하지 않습니다. 유일한 예외는 std::array<>
고정 된 크기의 C 스타일 배열을 래핑하므로 유일하게 합리적인 후보로 남을 것입니다.
그러나 니콜 올가미가 올바르게 코멘트 지적 간의 또 다른 중요한 차이점 std::initializer_list
및 (을 포함한 모든 다른 표준 컨테이너 std::array<>
) 후자 것들이있다이다 값 의미를 동시에 std::initializer_list
갖는 참조 시맨틱 . 복사 std::initializer_list
예를 들어, 여기에 포함 된 요소의 사본을 발생하지 않습니다.
또한 (다시 한 번 Nicol Bolas의 호의) 중괄호 초기화 목록에 대한 특수 컨테이너를 사용하면 사용자가 초기화를 수행하는 방식에 과부하가 걸릴 수 있습니다.
이것은 새로운 것이 아닙니다. 예를 들어, for (i : some_container)
에 의존하는 특정 방법 또는 독립형 기능의 존재 의 some_container
클래스입니다. C #은 .NET 라이브러리에 더 많이 의존합니다. 사실, 이것은 언어 사양을 복잡하게하지 않고도 클래스를 일부 언어 구조와 호환되도록 만들 수 있기 때문에 이것은 매우 우아한 솔루션이라고 생각합니다.
이것은 실제로 새로운 것이 아니며 많은 사람들이 지적한 바 있습니다.이 관행은 C ++에 있었고 C #에도 있습니다.
Andrei Alexandrescu는 이것에 대해 좋은 점을 언급했습니다. 가상의 "핵심"네임 스페이스의 일부로 생각할 수 있습니다. 그러면 더 이해가 될 것입니다.
: 그래서, 실제로 같은 뭔가 core::initializer_list
, core::size_t
, core::begin()
, core::end()
과에 이렇게. std
네임 스페이스 내부에 핵심 언어 구조 가있는 것은 불행한 우연입니다 .
표준 라이브러리에서 완벽하게 작동 할뿐만 아니라 표준 라이브러리에 포함되었다고해서 컴파일러가 영리한 트릭을 수행 할 수 없다는 의미는 아닙니다.
모든 경우에 할 수있는 것은 아니지만,이 유형은 잘 알려져 있거나 간단한 유형입니다.를 무시 initializer_list
하고 초기화 된 값이 무엇인지에 대한 메모리 이미지를 갖게됩니다.
즉 int i {5};
에 해당 될 수 있습니다 int i(5);
또는 int i=5;
심지어 intwrapper iw {5};
어디 intwrapper
사소한 생성자가 복용하는 int 이상의 클래스 래퍼 간단한이다initializer_list
It's not part of the core language because it can be implemented entirely in the library, just line operator new
and operator delete
. What advantage would there be in making compilers more complicated to build it in?
참고URL : https://stackoverflow.com/questions/15198807/why-isnt-stdinitializer-list-a-language-built-in
'Programing' 카테고리의 다른 글
추상 필드가 아닌 이유는 무엇입니까? (0) | 2020.09.02 |
---|---|
SIGINT는 SIGTERM, SIGQUIT 및 SIGKILL과 같은 다른 종료 신호와 어떤 관련이 있습니까? (0) | 2020.09.02 |
Haskell 오프라인 문서? (0) | 2020.09.02 |
java.lang.String에서 java.io.InputStream을 어떻게 얻을 수 있습니까? (0) | 2020.09.02 |
기본 메소드가있는 인터페이스는 언제 초기화됩니까? (0) | 2020.09.02 |