2012-03-10 5 views
4

저는 컴파일 타임에 형식을 정렬 할 수있는 방법을 찾고있었습니다. 이것은, 예를 들어 (효율적인) 컴파일 타임 타입 세트를 구현할 때 유용합니다.컴파일 타임에 형식을 정렬합니다.

모든 유형을 고유 한 정수로 매핑하는 방법이 있다면 분명히 할 수 있습니다. 그 어려운 이유 주제에 previous question에 대한 답변은 간결 캡처, 그리고 그것이 순서 얻기 위해 노력하는 다른 방법에 동일하게 적용하는 것처럼 보인다

컴파일러가 모든 컴파일 단위를 알 수있는 방법이없고, 링커는 타입에 대한 개념을 가지고 있지 않다.

사실, 컴파일러에 대한 도전은 상당히 클 것이다 : 모든 호출에서 모든 소스 파일에 대해 주어진 유형에 대해 동일한 정수가 반환되는지 확인해야합니다/주어진 두 유형간에 동일한 순서를 반환하지만 유형의 우주는 열려 있으며 현재 파일 외부의 유형에 대한 지식이 없습니다. 어려운 문제.

내가 가진 아이디어는 유형에 이름이 있다는 것입니다. 그리고 C++의 법칙에 따르면, 형식의 정규화 된 이름은 전체 프로그램에서 고유해야합니다. 그렇지 않으면 어떤 종류의 오류나 정의되지 않은 동작이 발생합니다.

  • 두 유형의 이름이 같은 경우 동일한 유형입니다.

  • 두 유형이 같은 유형 인 경우 이름이 같거나 서로 typedef입니다. 컴파일러는 typedef를 완전히 알고 있습니다.

이름은 문자열이며 순서는 문자열입니다. 그래서 내가 맞다면 이름에 따라 유형에 대해 전 세계적으로 일관된 순서를 정의 할 수 있습니다. 보다 구체적으로, 두 가지 유형의 순서는 완전히 해결 된 typedef가있는 유형의 이름 사이의 순서입니다. (형식이 typedef와 다르게 동작하는 것은 문제가 될 수 있습니다.)

물론 표준 C++에는 형식 이름을 검색 할 수있는 기능이 없습니다.

내 질문은 :

  • 내가 아무 잘못이 있습니까? 이론적으로 이것이 작동하지 않는 이유가 있습니까?

  • 언어 확장으로 컴파일 할 때 유형 이름 (그리고 이상적으로는 typedef로 해결 된 형식)에 액세스 할 수있는 컴파일러가 있습니까?

  • 다른 방법으로 수행 할 수 있습니까? 어떤 컴파일러가 있습니까?

(나는 같은 질문에 하나 개 이상의 질문을 정중 아니라고 인식하지만, 그들 앞에 동일한 기본 목구멍 - 청산에 별도의 세 가지 질문을 게시 이상한 것 같았다.)

+2

잘못된 프로그래밍 언어를 사용하고있는 것 같습니다. –

+0

"물론 표준 C++에는 형식 이름을 검색 할 수있는 기능이 없습니다." - http://en.wikipedia.org/wiki/Typeid – FailedDev

+0

C++에서 타입 정렬을 구현하려고 시도했지만 Standard C++에서는 불가능한 것처럼 보입니다. 아마도 GCC 플러그인을 써서이 작업을 수행 할 수 있지만 시도하지는 않았습니다. –

답변

1

유형의 완전한 이름이 전체 프로그램에서 고유해야합니다

하지만 다른 이름이 서로 다른 번역 단위로 별도의 익명의 네임 스페이스를 고려하는 경우 물론, 그것은 단지 사실 어떤 의미에서, 그들이 무엇인지 파악할 수있는 방법이 있습니다.

정말 다른 이름을 가지고 있다는 것을 알고있는 유일한 의미는 얽힌 링커 기호입니다. (컴파일러에 따라 다름)을 type_info::name()에서 가져올 수는 있지만 보장되지는 않으며 RTTI가있는 유형으로 제한되며 어쨌든 constexpr으로 표시되지 않으므로 사용할 수 없습니다 컴파일시의 값

type_info::before()에 의해 생성 된 주문에는 자연히 동일한 제한이 있습니다.

관심의 대상에서, 당신은 당신의 컴파일 타임 타입 주문으로 무엇을 달성하려고합니까?

+0

익명 네임 스페이스! 아주 좋은 점. 나는 그들을 잊었다. 내 질문에 정규화 된 이름의 기능은 반드시 직접적으로 노출하는 것이 아니라 유형에 대해 일관된 컴파일 시간 순서를 구현하기위한 메커니즘으로 (가상의) 설명합니다. 그 목적을 위해 (내가 올바르게 생각한다면) 일관성있는 한 우리가 주문한 순서는 어디 까지나 중요하지 않습니다. type_info :: name()에 대해서는 typeid 연산자 자체가 불행하게도 constexpr이 아니기 때문에 우리를 아주 멀리하지는 않습니다. – glaebhoerl

+0

나의 사용 사례는 다음과 같습니다. "필드 레이블"을 레코드 유형간에 공유 할 수있는 레코드 유형 시스템을 구현하고 싶습니다. 그러나 레코드의 필드 순서는 중요하지 않습니다. 필드 레이블의 "이름"은 더미 유형으로 표시됩니다. 실제로는 몇 가지 순서로 기록해야하지만 레코드 는 Record 와 완벽하게 상호 운용 될 수 있어야합니다. 따라서 형식은 목록이 아닌 집합과 유사해야합니다. 그리고 세트를 구현하려면 연산자 <()를 사용하는 것이 좋습니다. 그것은없이 가능하지만, 더 좋네요. – glaebhoerl

+0

(레코드의 경우 완전히 잊어 버린 또 다른 것은 type_info :: before()입니다. 점프에서 점프하는 것은 GHC/Haskell이 Typeable 클래스를 구현하는 방식이었습니다. 그러나 typeid 및 type_info :: before()가 constexpr (런타임에 그것들을 구현할 수있는 이유가 있겠지만 컴파일 타임에 없을 것입니다.) – glaebhoerl

관련 문제