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

Aug 19 2020

พิจารณาเทมเพลตคลาสต่อไปนี้:

template<typename T>
struct S 
{    
    template<auto = T()> 
    void f();
};

เป็นรูปแบบที่ไม่ดีในการสร้างอินสแตนซ์Sกับพารามิเตอร์เทมเพลตTซึ่งauto = T()รูปแบบที่ไม่ดีหรือไม่?

int main()
{
    S<int> a;    // ok
    S<int&> b;   // error
    S<int()> c;  // gcc ok, clang error
}

ดูเหมือนจะเป็นเช่นนั้น แต่ปัญหาอยู่cที่ซึ่งSสร้างอินสแตนซ์ด้วยประเภทฟังก์ชัน gcc ก็โอเคกับสิ่งนี้ในขณะที่เสียงดังกล่าวว่า:

error: cannot create object of function type 'int ()'

ซึ่งสมเหตุสมผล เนื่องจาก gcc วินิจฉัยการสร้างอินสแตนซ์ด้วยint&ฉันจึงสงสัยว่านี่เป็นข้อบกพร่องของ gcc ถูกต้องหรือไม่จำเป็นต้องมีการวินิจฉัยสำหรับรหัสนี้?

คำตอบ

1 LanguageLawyer Aug 19 2020 at 14:10

นี่คือCWG1635 :

1635 อาร์กิวเมนต์เริ่มต้นของเทมเพลตมีความคล้ายคลึงกับอาร์กิวเมนต์เริ่มต้นอย่างไร?

อาร์กิวเมนต์ของฟังก์ชันเริ่มต้นจะถูกสร้างอินสแตนซ์เมื่อจำเป็นเท่านั้น อาร์กิวเมนต์เทมเพลตเริ่มต้นเป็นจริงหรือไม่ ตัวอย่างเช่นรูปแบบที่ดีต่อไปนี้หรือไม่?

 #include <type_traits>

 template<class T>
 struct X {
   template<class U = typename T::type>
   static void foo(int){}
   static void foo(...){}
 };

 int main(){
   X<std::enable_if<false>>::foo(0);
 }

นอกจากนี้ผลของการค้นหายังเหมือนกันหรือไม่? เช่น,

 struct S {
   template<typename T = U> void f();
   struct U {};
 };