2013-04-08 3 views
22

this SO question에 응답 할 때 표준 형식 (이미 C++ 03, 여전히 C++ 11)에서 비 형식형 템플릿 인수로만 주소를 사용할 수 있음을 발견했습니다. 양식 & id-expression (일부 예외 포함).포인터가 아닌 형식의 템플릿 인수

하지만 대답 할 수 없었습니다. 이유는입니다.

:

14.3.2 템플릿이 아닌 형태 인수 [temp.arg.nontype]

비 유형에 대한 템플릿 인수 비 템플릿 템플릿 파라미터 중 하나 여야한다 [...]

정적 저장소> 지속 시간 및 외부 또는 내부 연결 이있는 개체의 주소를 지정하는 상수 식 (5.19) 또는 외부 또는 내부 연결이있는 함수 (함수 템플릿 및 함수 템플릿 포함) -ids하지만 exc 비정규 클래스 멤버를 사용하는 경우, &은 이름이 함수 또는 배열을 참조하는 경우 생략 될 수 있으며 해당 템플릿 매개 변수가 참조 인 경우 생략해야한다는 점을 제외하고는 & ID 표현으로 표현됩니다 (괄호 무시). [...]

(n3485 강조 광산)

예 :

using TFoobar = int (*)(); 
template < TFoobar tp > struct foo_struct{}; 

int foobar() { return 42; } 
constexpr TFoobar pFoobar = &foobar; 

foo_struct < &foobar > o0; // fine 
foo_struct <pFoobar> o1; // ill-formed 

나는 그것이 번역 상 함께 할 수있는 뭔가가 생각, 즉 컴파일러는 많이 알고하지 않습니다 주소에 대해서. 그러나, 왜 그것이 허용되지 않습니까? 컴파일러가 pFoobar&foobar으로 바꾸기 위해 매크로 대체와 비슷한 것을 사용할 수 없어야합니까?

+1

아주 좋은 질문입니다. –

+1

나는 그것이 보수적 인 변화를 만드는 문제라고 생각한다.C++ 11은 컴파일러 구현자를 위해 일을 쉽게하기 위해 언어가하는 엄격한 방법으로 가득 차 있습니다. C++ 11을 위와 같이 확장 할 수도 있지만 C++ 14 이상에서는 문제가됩니다! – Yakk

+0

이러한 제한 사항을 제거하기위한 제안 [http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4268.html]이 있습니다. – dyp

답변

1

클래스 Foo<&X>Foo<&Y>을 모두 정적 멤버 int Bar으로 간주합니다. 링커는 프로그램에 1 또는 2 개의 Bar 개체가 있는지 여부를 알 수 있어야합니다. 이제 링커가 &X&Y에 값을 할당 할 가능성이 가장 큰 파티이기도합니다.

표준을 다시보십시오. 작성된대로 컴파일러는 실제 주소을 링커에 전달할 필요가 없습니다. 대신 id-expression을 전달합니다. 링커는 이미 숫자 주소를 할당하기 전에 두 개의 id-expression이 같은지 여부를 판단 할 수 있습니다.

+1

실제 주소 대신 대체 주소를 사용할 수 있다는 사실을 알고 있습니다. 하지만 그게'constexpr' 객체가 포인터 템플릿 인자로 사용될 수없는 이유는 무엇입니까? – dyp

+0

그리고 DyP 주석에 추가하기 위해 함수에 대한 constexpr 포인터가 만들어지면 그 값을 계산하여 링커 ('& id' 또는'nullptr')에 넘길 수 있습니다. – Synxis

+0

@Synxis : 아니요, 컴파일러는 함수에 대한 (constexpr) 포인터의 값을 계산할 수 없습니다. 링커가 함수에 주소를 제공 할 것이기 때문입니다. – MSalters

0
  1. 변수는 런타임에만 설정되기 때문에 변수가 될 수 없습니다.
  2. 주소의 은 컴파일 타임에 알 수 없기 때문에 constexpr 일 수 없습니다. 대부분의 경우 실행 전 재배치 후에 만 ​​수정됩니다.
  3. 이론적으로는 (표준에서는 허용되지 않지만) 산술식이 될 수 있지만 일반적으로 배열 요소의 주소의 경우 arr + i 대신 &arr[i]을 사용하면됩니다.
+0

constexpr이 될 수없는 것은 무엇입니까? 함수 주소는 컴파일시 (링크 타임 포함)에 알려집니다. 또한, 재배치는 주로 공유 라이브러리에서 발생하며, 최신 시스템에서는 'exe'가 종종 재배치되지 않습니다. – Synxis

+0

광고 3 : 표준을 올바르게 해석하면 상수 표현이 허용됩니다. 함수 (함수 ptrs)에 대해 금지되어 있습니다. 산술 표현이 함수 ptr에 대해별로 이해가 안되는 이유를 알 수 있지만 함수 ptr로 평가되는 상수 표현이 내 말이 맞습니다. 내 OP (또는 Synxis 원래 질문)의 예를 참조하십시오. – dyp

관련 문제