정적 인 (constexpr) 멤버의 연결에 대한 많은 질문이 있습니다.정적 constexpr 멤버가있는 템플릿 클래스의 ODR
하지만 템플릿 클래스를 아웃 오브 라인 정의로 사용하는 것이 헤더 파일에서 작동하지만 특수 클래스에서는 작동하지 않는 이유가 궁금합니다.
이 링커 오류없이 작동하는):
template<typename, typename>
struct Foobar;
template<typename T>
struct Foobar<int, T> {
static constexpr std::array<int, 1> a = {{1}};
};
template<typename T>
constexpr std::array<int, 1> Foobar<int, T>::a;
// foo.cpp
std::cout << Foobar<int, int>::a[0] << "\n";
// bar.cpp
std::cout << Foobar<int, int>::a[0] << "\n";
의 objdump를 :
foo.o : 0000000000000000 w O .rodata._Z6FoobarIiiE1aE 0000000000000004 _Z6FoobarIiiE1aE
bar.o : 0000000000000000 w O .rodata._Z6FoobarIiiE1aE 0000000000000004 _Z6FoobarIiiE1aE
링크 된 파일 : 0000000000475a30 w O .rodata 0000000000000004 _Z6FoobarIiiE1aE
b) 하지 않습니다 (다중 정의) :
template<typename>
struct Foobar;
template<>
struct Foobar<int> {
static constexpr std::array<int, 1> a = {{1}};
};
constexpr std::array<int, 1> Foobar<int>::a;
// foo.cpp
std::cout << Foobar<int>::a[0] << "\n";
// bar.cpp
std::cout << Foobar<int>::a[0] << "\n";
의 objdump를 :
foo.o 0000000000000100 g O .rodata 0000000000000004 _Z6FoobarIiE1aE
bar.o : 0000000000000420 g O .rodata 0000000000000004 _Z6FoobarIiE1aE
우리가 볼 무엇
, 아웃 오브 라인 정의 오브젝트 파일 안에 다른 주소를 가지고있다 (예제 b)). 당신에게
내 질문 :
- 이 템플릿 트릭을 사용하여 저장할 수 있나요? 단점은 무엇입니까?
- 미래의 b와 같은 경우 odr의 정의를 완화하는 것이 유용할까요?
미리 감사드립니다.
"* 미래의 나처럼 이러한 경우에 대한 ODR의 정의를 휴식하는 것이 유용 할 것인가 *?"이미 C++ 17 : constexpr 정적 데이터 멤버는 암묵적으로'inline'입니다. – ildjarn
멋진! 그것을 기다릴 수 없어. :) – Viatorus