2016-12-14 11 views
2

another question에서 보았습니다. 클래스 정의 또는 인라인 함수에서 ODR 위반을 일으킬 수 있으므로 헤더 파일을 통해 익명 네임 스페이스의 개체 나 함수를 사용할 수 없다는 것을 깨달았습니다. 이 경우, 또는 constexprstatic 객체를 inline 함수 또는 클래스에 안전하게 사용할 수 있습니까? 예를 들어, CONSTANTnamespace 아래에 있으면 안전하지 않을 수 있지만 정적 연결이있는 상수를 사용해도됩니까?ODR 규정 준수 헤더 파일에 상수를 사용합니다.

// some header file to be included by multiple .cpp files 
static const/*expr*/ int CONSTANT = 2; 

inline int f() { 
    return CONSTANT; 
} 

class Cls { 
    int mem = CONSTANT; 
}; 
+1

적어도 C++ 17에서는 더 이상 문제가되지 않습니다. 이상하게도 타입 별칭이 문제를 해결할 수 있습니다 :'CONSTANT = std :: integral_constant ; – Barry

+0

@MM의 인용문에서 "객체가 odr-used가 아닙니다"라는 것을 배워라. –

+0

N4606 (isocpp.org에 따른 최신 표준 초안)은 여전히 ​​"객체가 odr-used가 아닙니다" –

답변

4

이 코드는 정상입니다. 전체 단락 (C++ 14 [basic.def.odr은/6.2])이다 : 이름을 대응 D, 각 정의

가 고개 34 항에있어서, 상기 정의에 정의 된 항목에 해당한다 D이거나 동일한 개체, 과부하 해결 후 및 부분 템플릿 전문화의 일치 후, 이름이 비 휘발성 const 개체를 참조 할 수 있다는 점을 제외하고는 개체가 동일한 리터럴 형식 인 경우 내부 또는 연결이없는 const 개체를 참조해야합니다. 모든 정의가 D이고 개체가 상수 식으로 초기화되고 개체가 odr- 사용이 아니며 개체의 정의가 모두 D 인 경우 동일한 값을 갖습니다.

  • 이 이름은 CONSTANT 사실 비를 참조 않습니다 및

이 사용은 일부 "... ... 제외하고 ... 그리고"는에서 모든 조건에 일치 않습니다 휘발성 const 내부 연결이있는 개체

  • 모든 정의에서 동일한 리터럴 유형이 f()입니다.
  • 상수 표현 2으로 초기화됩니다.
  • odr-used이 아닙니다.
  • 모든 정의에서 동일한 값을 가지고 있습니다 (f()). 당신이 odr- 일어날 경우가 f()을 아프게하지 않는, 즉 -
  • 요점은 "그것은 f()을 사용 ODR-아니다"뜻한다 "그것은 이 ODR 사용되는 아니다" 프로그램의 다른 곳에서CONSTANT을 사용하십시오.

    +1

    확실히 "D의 정의 내에서 odr-used가 아닙니다"라는 뜻입니다. –

    +0

    @ T.C. https://github.com/cplusplus/draft/pull/1243 –

    +0

    완료되었습니다. 표준이 변경되었습니다! –