Khởi tạo thành viên tĩnh trong một mẫu lớp


148

Tôi muốn làm điều này:

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

nhưng tôi không thể something_relevantlà loại không thể thiếu. Nó không phụ thuộc vào T, nhưng mã hiện tại phụ thuộc vào nó là thành viên tĩnh của S.

Vì S là mẫu, tôi không thể đặt định nghĩa bên trong tệp được biên dịch. Làm thế nào để tôi giải quyết vấn đề này?


cũng áp dụng cho std::stringloại
Trevor Boyd Smith

Vì c ++ 11, từ khóa nội tuyến đã thay đổi để các biến tĩnh có thể được khởi tạo tại điểm khai báo. Vì vậy, khai báo cho điều này sẽ trông giống như "nội tuyến tĩnh đôi gì đó_relevant = 1,5;"

@ user8991265 Tôi tin rằng các biến nội tuyến có sẵn kể từ C ++ 17, không phải C ++ 11.
zupazt3

Câu trả lời:


195

Chỉ cần xác định nó trong tiêu đề:

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

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

Vì nó là một phần của mẫu, vì với tất cả các mẫu, trình biên dịch sẽ đảm bảo nó chỉ được xác định một lần.


4
@sbi: nó không vi phạm quy tắc một định nghĩa à?
Alexandre C.

7
Không, không phải nếu chúng ta đang nói mẫu. Nếu không, các mẫu chức năng cũng sẽ làm như vậy.
sbi

1
@sbi, @Prasoon: thực sự Prasoon dường như là người đầu tiên. Nhưng tôi vẫn chấp nhận sbi vì nhận xét về ODR (đó là mối quan tâm chính của tôi).
Alexandre C.

1
@sbi chỉ di chuột qua văn bản :)
Johannes Schaub - litb

5
@Johannes: Chết tiệt, tôi ở đây được một năm và tôi không biết điều đó! Tôi còn thiếu gì nữa? (Tôi vẫn còn nhớ sự xấu hổ khi tôi phát hiện ra rằng hai số xuất hiện khi tôi nhấp vào số phiếu không phải là lỗi, nhưng là một tính năng.) <goes_playing>Wow, khi tôi di chuột qua tên của bạn, tôi thấy đại diện của bạn! Tôi cũng không biết điều đó. @Prasoon: Không, bạn nói đúng, tôi đã đến nơi hiện tại. (Đó là lý do tại sao tôi đã bình chọn câu trả lời của bạn, BTW.)
sbi


31

Điều này sẽ làm việc

template <typename T>
 struct S
 {

     static double something_relevant;
 };

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

Tôi đã không xác định biến template<typename T> double S<T>::something_relevant=1.5;)Something_relevant (Tôi đã xóa lỗi trình biên dịch. Bạn có thể cho tôi biết lý do là gì không?
goodman
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.