การเริ่มต้นสมาชิกแบบคงที่ในเทมเพลตคลาส


148

ฉันต้องการทำสิ่งนี้:

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

แต่ฉันทำไม่ได้เนื่องจากsomething_relevantไม่ใช่ประเภทที่สมบูรณ์ มันไม่ได้ขึ้นอยู่กับแต่รหัสที่มีอยู่ขึ้นอยู่กับมันเป็นสมาชิกคงที่ของTS

เนื่องจาก S เป็นแม่แบบฉันไม่สามารถใส่คำจำกัดความไว้ในไฟล์ที่คอมไพล์ได้ ฉันจะแก้ปัญหานี้ได้อย่างไร


ใช้ได้กับstd::stringประเภท
Trevor Boyd Smith

ตั้งแต่ c ++ 11 คีย์เวิร์ด inline มีการเปลี่ยนแปลงเพื่อให้ตัวแปรสแตติกสามารถเริ่มต้นได้ที่จุดประกาศ ดังนั้นการประกาศนี้จะดูเหมือน "inline static double something_relevant = 1.5;"

@ user8991265 ฉันเชื่อว่าตัวแปรอินไลน์มีให้ตั้งแต่ C ++ 17 ไม่ใช่ C ++ 11
zupazt3

คำตอบ:


195

เพียงกำหนดไว้ในส่วนหัว:

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

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

เนื่องจากเป็นส่วนหนึ่งของเทมเพลตเช่นเดียวกับเทมเพลตทั้งหมดคอมไพเลอร์จะตรวจสอบให้แน่ใจว่ามีการกำหนดเพียงครั้งเดียว


4
@sbi: มันไม่ได้ละเมิดกฎความหมายเดียว?
Alexandre C.

7
ไม่ไม่ใช่ถ้าเรากำลังพูดถึงเทมเพลต มิฉะนั้นแม่แบบฟังก์ชั่นก็ควรทำเช่นกัน
sbi

1
@sbi, @Prasoon: จริง ๆ แล้ว Prasoon ดูเหมือนจะเป็นคนแรก แต่ฉันยังคงยอมรับ sbi เพราะความคิดเห็นเกี่ยวกับ ODR (ซึ่งเป็นข้อกังวลหลักของฉัน)
Alexandre C.

1
@sbi เพียงเลื่อนเมาส์ไปที่ข้อความ :)
Johannes Schaub - litb

5
@Johannes: Dammit ฉันอยู่ที่นี่มาหนึ่งปีแล้วและฉันก็ไม่รู้เหมือนกัน! มีอะไรอีกบ้างที่ขาดหายไป? (ฉันยังจำความอัปยศเมื่อฉันค้นพบว่าตัวเลขสองตัวที่ปรากฏขึ้นเมื่อฉันคลิกที่จำนวนคะแนนไม่ใช่ข้อผิดพลาด แต่เป็นคุณสมบัติ) <goes_playing>ว้าวเมื่อฉันวางตัวเหนือชื่อของคุณฉันเห็นตัวแทนของคุณ! ฉันก็ไม่รู้เหมือนกัน @ ประสงค์: ไม่คุณพูดถูกฉันทำซ้ำแล้วซ้ำอีก (นั่นเป็นเหตุผลที่ฉันได้คะแนนโหวตคำตอบของคุณ BTW.)
sbi

37

ตั้งแต่ C ++ 17 ตอนนี้คุณสามารถประกาศสมาชิกแบบคงinlineที่ซึ่งจะกำหนดตัวแปรในการกำหนดคลาส:

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

สด: https://godbolt.org/g/bgSw1u


1
นี่คือคำตอบที่ยอดเยี่ยม สั้นและแม่นยำ ดูเพิ่มเติมที่en.cppreference.com/w/cpp/language/static#Static_data_membersสำหรับข้อมูลเพิ่มเติม
andreee

31

สิ่งนี้จะได้ผล

template <typename T>
 struct S
 {

     static double something_relevant;
 };

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

ฉันไม่ได้กำหนดตัวแปรtemplate<typename T> double S<T>::something_relevant=1.5;)some_relevant (ฉันลบข้อผิดพลาดการโยนคอมไพเลอร์คุณช่วยบอกหน่อยได้ไหมว่าอะไรคือเหตุผล
Goodman
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.