我知道,有很多關於靜態(constexpr)成員鏈接的回答問題。模板類的ODR與靜態constexpr成員
但我想知道,爲什麼在頭文件中使用模板類線外定義,但不適用於專門的類。
a)本工程不鏈接錯誤:
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這樣的情況下,像b在未來的定義有用*?」早在C++ 17:constexpr靜態數據成員是隱式「內聯」的。 – ildjarn
可愛!不能等待它。 :) – Viatorus