Inisialisasi anggota statis dalam templat kelas

148

Saya ingin melakukan ini:

template <typename T>
struct S
{
    ...
    static double something_relevant = 1.5;
};

tapi saya tidak bisa karena something_relevantitu bukan tipe integral. Itu tidak bergantung pada T, tetapi kode yang ada tergantung padanya menjadi anggota statis S.

Karena S adalah templat, saya tidak bisa memasukkan definisi di dalam file yang dikompilasi. Bagaimana saya mengatasi masalah ini?

Alexandre C.
sumber
juga berlaku untuk std::stringmengetik
Trevor Boyd Smith
Sejak c ++ 11 inline kata kunci telah berubah sehingga variabel statis dapat diinisialisasi pada titik deklarasi. Jadi deklarasi untuk ini akan terlihat seperti "inline static double something_relevant = 1.5;"
@ user8991265 Saya percaya variabel inline tersedia sejak C ++ 17, bukan C ++ 11.
zupazt3

Jawaban:

196

Cukup tentukan di header:

template <typename T>
struct S
{
    static double something_relevant;
};

template <typename T>
double S<T>::something_relevant = 1.5;

Karena ini adalah bagian dari templat, karena dengan semua templat kompiler akan memastikan itu hanya ditentukan sekali.

sbi
sumber
4
@ sbi: bukankah itu melanggar aturan satu definisi?
Alexandre C.
7
Tidak, tidak jika kita berbicara template. Jika tidak, templat fungsi akan melakukannya juga.
sbi
1
@sbi, @Prasoon: sebenarnya Prasoon sepertinya yang pertama. Tapi saya masih menerima sbi karena komentar tentang ODR (yang merupakan perhatian utama saya).
Alexandre C.
1
@sbi hanya mengarahkan kursor pada teks :)
Johannes Schaub - litb
5
@ Johnannes: Sialan, saya di sini selama satu tahun dan saya tidak tahu itu! Apa lagi yang saya lewatkan? (Saya masih ingat rasa malu ketika saya menemukan bahwa dua angka yang muncul ketika saya mengklik jumlah suara bukan bug, tetapi fitur.) <goes_playing>Wow, ketika saya mengarahkan kursor ke nama Anda, saya melihat perwakilan Anda! Saya juga tidak tahu itu. @Prasoon: Tidak, Anda benar, saya berulang tiba di tempat itu sekarang. (Itu sebabnya saya memilih jawaban Anda, BTW.)
sbi
37

Sejak C ++ 17, Anda sekarang dapat mendeklarasikan anggota statis menjadi inline, yang akan menentukan variabel dalam definisi kelas:

template <typename T>
struct S
{
    ...
    static inline double something_relevant = 1.5;
};

langsung: https://godbolt.org/g/bgSw1u

xaxxon
sumber
1
Ini jawaban yang sangat bagus. Singkat dan tepat. Lihat juga en.cppreference.com/w/cpp/language/static#Static_data_members untuk informasi lebih lanjut.
andreee
31

Ini akan bekerja

template <typename T>
 struct S
 {

     static double something_relevant;
 };

 template<typename T>
 double S<T>::something_relevant=1.5;
Prasoon Saurav
sumber
Saya tidak mendefinisikan variabel something_relevant (saya menghapus template<typename T> double S<T>::something_relevant=1.5;)kesalahan melempar kompiler. Bisakah Anda memberi tahu saya apa alasannya?
Goodman