cppreference.com 에 따르면 size_t여러 헤더, 즉
<cstddef>
<cstdio>
<cstring>
<ctime>
그리고 C ++ 11부터
<cstdlib>
<cwchar>
우선 왜 이것이 사실인지 궁금합니다. 이것은 DRY 원칙 에 위배되지 않습니까? 그러나 내 질문은 다음과 같습니다.
위의 헤더 중 어떤 것을 사용하려면 포함해야 size_t합니까? 전혀 중요합니까?
cppreference.com 에 따르면 size_t여러 헤더, 즉
<cstddef>
<cstdio>
<cstring>
<ctime>
그리고 C ++ 11부터
<cstdlib>
<cwchar>
우선 왜 이것이 사실인지 궁금합니다. 이것은 DRY 원칙 에 위배되지 않습니까? 그러나 내 질문은 다음과 같습니다.
위의 헤더 중 어떤 것을 사용하려면 포함해야 size_t합니까? 전혀 중요합니까?
<cstddef>을 위해std::size_t
std::size_t. 이 스레드를 읽는 사람이 이로 인해 레거시 유형 / 함수를 사용하도록 오해 당할 것 같지는 않지만 그렇지 않은지 확인하고 싶다면 충분히 공정합니다!
답변:
내가 가져온 함수와 유형을 최소화하고 싶다고 가정하면 함수를 cstddef선언하지 않고 6 유형 만 선언하므로 함께 갈 것입니다 . 다른 것들은 당신에게 중요하지 않은 특정 도메인 (문자열, 시간, IO)에 초점을 맞 춥니 다.
참고 cstddef만 정의하는 보장 std::size_t정의이며, size_t네임 스페이스 std가 있지만, 수 전역 네임 스페이스 (효과적으로, 일반에이 이름을 제공합니다 size_t).
반면에 stddef.h(도 C 가능 헤더 임) 정의 보장 size_t글로벌 네임 스페이스하고 있다 또한 제공한다 std::size_t.
size_tfrom cstddef이 동일하고 항상 다른 사람과 동일 하다는 보장이 있습니까? 같은 일반적인 정의가 공통 헤더 파일이 있어야처럼 보인다 size_t...
cstddef.
<cstddef>할 수도 있고 정의하는 내부 헤더를 모두 포함 할 수도 size_t있습니다.
csttddef대답에 오타? 어쩌면 cstddef의미입니까?
실제로 여러 헤더의 시놉시스 (C ++ 표준에 포함됨)에는 size_t유형을 정의 할뿐만 아니라 추가 헤더가 명시 적으로 포함 됩니다 size_t( <cX>헤더는 <X.h>제거 size_t가 표시되지 않은 변경 사항 이있는 ISO C 헤더 일 뿐이 므로 C 표준을 기반으로 함).
C ++ 표준은 그러나, 을 의미 <cstddef>의 정의std::size_t
따라서 <cstddef>유형 만 소개하고 기능은 제공하지 않기 때문에이 헤더를 사용하여 std::size_t사용할 수 있도록 합니다.
몇 가지 사항에 유의하십시오.
의 유형은 헤더를 포함하지 않고 std::size_t사용하여 얻을 수 있습니다.decltype
넌 계획 어쨌든 코드에서 타입 정의를 소개하는 경우 (즉, 당신은 컨테이너를 작성하고 제공하기 원하기 때문에 size_type형식 정의를) 전역 사용할 수 있습니다 sizeof, sizeof...또는 alignoftheose 사업자가 반환 이후 전혀 헤더를 포함하지 않고 당신의 유형을 정의하는 연산자를 std::size_t당 표준 정의이며 다음과 같이 사용할 수 decltype있습니다.
using size_type = decltype(alignof(char));
std::size_tstd::size_t인수가있는 함수는 있지만 그 자체로는 전역 적으로 표시되지 않습니다 .
암시 적으로 선언 된 전역 할당 및 할당 해제 함수
void* operator new(std::size_t);
void* operator new[](std::size_t);
void operator delete(void*);
void operator delete[](void*);
소개하지 마십시오 size_t, std또는 std::size_t과
적절한 헤더를 포함하여 이름이 선언되지 않는 한 참조
std하거나std::size_t잘못된 형식입니다.
std::size_t동일한 네임 스페이스에서 동일한 유형을 참조하는 여러 typedef를 가질 수 있지만 사용자는 재정의 할 수 없습니다 .
의 여러 정의의 발생,하지만 size_t내가 std당 완벽하게 유효 7.1.3 / 3 , 어떤 선언을 추가 할 수 없습니다 namespace std와 같은 당 17.6.4.2.1 / 1 :
C ++ 프로그램의 동작은 별도로 지정하지 않는 한 네임 스페이스 std 또는 네임 스페이스 std 내의 네임 스페이스에 선언 또는 정의를 추가하는 경우 정의되지 않습니다.
size_t네임 스페이스에 대한 적절한 typedef를 추가하는 것은 7.1.3을 위반하지 않지만 17.6.4.2.1을 위반 하고 정의되지 않은 동작으로 이어집니다.
설명 : 7.1.3 을 잘못 해석 하지 말고 선언이나 정의를 추가하지 마십시오 std(typedef가 템플릿 전문화가 아닌 몇 가지 템플릿 전문화 사례 제외). 확장namespace std
std중복 typedef가 불법이기 때문에 재정의 typedef를 추가하는 것이 유효 하지 않다고 주장하지 않습니다 . namespace std합법적인지 여부에 관계없이 정의를 추가 할 수 없기 때문에 불법이라고 말합니다 .
모든 표준 라이브러리 헤더 파일은 동일한 정의를 갖습니다. 자신의 코드에 어떤 것을 포함시키는지는 중요하지 않습니다. 내 컴퓨터에는 _stddef.h. 이 파일은 나열한 모든 파일에 포함되어 있습니다.
/*
Define the size_t type in the std namespace if in C++ or globally if in C.
If we're in C++, make the _SIZE_T macro expand to std::size_t
*/
#if !defined(_SIZE_T) && !defined(_SIZE_T_DEFINED)
# define _SIZE_T_DEFINED
#if defined(_WIN64)
typedef unsigned __int64 size_t;
#else
typedef unsigned int size_t;
#endif
# if defined(__cplusplus)
# define _SIZE_T std::size_t
# else
# define _SIZE_T size_t
# endif
#endif
size_t애초에 왜 필요한 가요?
size_t. 더 이식 가능하게 using size_t = decltype( sizeof( 42 ) ). 그러나 <stddef.h>거의 비용이 들지 않기 때문에 필요가 없습니다 .
헤더 없이도 할 수 있습니다.
using size_t = decltype(sizeof(int));
using size_t = decltype(sizeof 1); // The shortest is my favourite.
using size_t = decltype(sizeof "anything");
이는 C ++ 표준에 다음이 필요하기 때문입니다.
sizeof및 의 결과는sizeof...유형 상수입니다std::size_t. [참고 :std::size_t표준 헤더<cstddef>(18.2)에 정의되어 있습니다. — 끝 참고]
즉, 표준은 다음을 요구합니다.
static_assert(std::is_same<decltype(sizeof(int)), std::size_t>::value,
"This never fails.");
또한 동일한 typedef-name 의 다른 모든 선언 과 일치 typedef하는 한 전역 및 std네임 스페이스 에서이 선언 을 만드는 것이 완벽합니다.typedef (일치하지 않는 선언에서 컴파일러 오류가 발생 함).
이 때문입니다:
§7.1.3.1 typedef-name 은 클래스 선언 (9.1)이나 열거 형 선언처럼 새로운 유형을 도입하지 않습니다.
§7.1.3.3 지정된 클래스가 아닌 범위에서 typedef지정자를 사용하여 해당 범위에서 선언 된 모든 형식의 이름을 이미 참조하는 형식을 참조하도록 재정의 할 수 있습니다.
회의론자들에게 이것이 네임 스페이스에 새로운 유형의 추가를 구성한다고 말합니다. std 하고 그러한 행위는 표준에 의해 명시 적으로 금지되고 있으며 이것이 UB이고 그게 전부 ; 나는 이러한 태도가 근본적인 문제에 대한 더 깊은 이해를 무시하고 부정하는 것이라고 말해야합니다.
표준은 네임 스페이스에 새로운 선언과 정의를 추가하는 것을 금지합니다. std그렇게하면 사용자가 표준 라이브러리를 엉망으로 만들고 그의 다리 전체를 쏠 수 있기 때문입니다. 표준 작가의 경우, 사용자가하지 말아야 할 모든 일을 금지하고 중요한 일 (그리고 그 다리)을 놓칠 위험이있는 것보다 사용자가 몇 가지 특정 일을 전문화하고 좋은 조치를 위해 다른 일을하는 것을 금지하는 것이 더 쉬웠습니다. 과거에는 표준 컨테이너가 불완전한 유형으로 인스턴스화되지 않도록 요구할 때이를 수행했지만 실제로 일부 컨테이너는 잘 수행 할 수 있습니다 ( Matthew H. Austern의 The Standard Librarian : Containers of Incomplete Types 참조 ).
... 결국 모든 것이 너무 어둡고 너무 잘 이해되지 않는 것처럼 보였습니다. 표준화위원회는 STL 컨테이너가 불완전한 유형으로 작동해서는 안된다고 말하는 것 외에는 선택의 여지가 없다고 생각했습니다. 좋은 측정을 위해 우리는이 금지를 나머지 표준 라이브러리에도 적용했습니다.
... 돌이켜 보면 이제 기술이 더 잘 이해되었으므로 그 결정은 여전히 기본적으로 옳은 것 같습니다. 예, 어떤 경우에는 일부 표준 컨테이너를 구현하여 불완전한 유형으로 인스턴스화 할 수 있지만 다른 경우에는 어렵거나 불가능하다는 것도 분명합니다. 을 사용하여 시도한 첫 번째 테스트가
std::vector쉬운 경우 중 하나 일 가능성이 큽니다.
언어 규칙 std::size_t이 정확히되어야 한다는 점을 감안할 때 decltype(sizeof(int)),하는 namespace std { using size_t = decltype(sizeof(int)); }것은 아무것도 깨뜨리지 않는 일 중 하나입니다.
C ++ 11 이전에는 많은 템플릿을 사용하지 않고는 하나의 간단한 명령문에서 결과 decltype유형을 선언 할 방법이 없었습니다 sizeof. size_t다른 대상 아키텍처에서 다른 유형을 별칭으로 지정하지만의 결과에 대해서만 새로운 내장 유형을 추가하는 것은 우아한 솔루션 sizeof이 아니며 표준 내장 typedef가 없습니다. 따라서 당시 가장 이식 가능한 솔루션은 size_t특정 헤더와 문서 에 유형 별칭 을 넣는 것이 었습니다 .
C ++ 11에는 표준의 정확한 요구 사항을 하나의 간단한 선언으로 기록하는 방법이 있습니다.
size_t!" 1 분 후 Mary는 "OMG! size_t표준 라이브러리 헤더와 Tom이 편집중인 프로젝트 헤더에 대한 7 개의 정의가 있습니다! 타사 라이브러리에 더 많은 것이있을 것입니다!" xkcd.com/927
size_t이지만 이것은 OP의 실제 질문에 대답하지 않습니다. 마치 내가 FILE선언 된 헤더를 요청 하고 내 자신의 것을 작성하도록 제안하는 것과 같습니다.