กำหนดคลาสเทมเพลตดังต่อไปนี้:
template<typename Type, typename IDType=typename Type::IDType>
class Mappings
{
public:
...
Type valueFor(const IDType& id) { // return value }
...
};
มีคนส่งต่อประกาศคลาสนี้ในไฟล์ส่วนหัวได้อย่างไร
กำหนดคลาสเทมเพลตดังต่อไปนี้:
template<typename Type, typename IDType=typename Type::IDType>
class Mappings
{
public:
...
Type valueFor(const IDType& id) { // return value }
...
};
มีคนส่งต่อประกาศคลาสนี้ในไฟล์ส่วนหัวได้อย่างไร
คำตอบ:
นี่คือวิธีที่คุณจะทำ:
template<typename Type, typename IDType=typename Type::IDType>
class Mappings;
template<typename Type, typename IDType>
class Mappings
{
public:
...
Type valueFor(const IDType& id) { // return value }
...
};
โปรดทราบว่าค่าเริ่มต้นอยู่ในการประกาศไปข้างหน้าและไม่อยู่ในคำจำกัดความที่แท้จริง
คุณสามารถประกาศอาร์กิวเมนต์เริ่มต้นสำหรับเทมเพลตได้สำหรับการประกาศเทมเพลตครั้งแรกเท่านั้น หากคุณต้องการอนุญาตให้ผู้ใช้ส่งต่อประกาศเทมเพลตคลาสคุณควรระบุส่วนหัวการส่งต่อ หากคุณต้องการส่งต่อประกาศแม่แบบชั้นเรียนของคนอื่นโดยใช้ค่าเริ่มต้นคุณจะโชคไม่ดี!
คุณสามารถประกาศคลาสเท็มเพลตซึ่งนิยามระบุอาร์กิวเมนต์เริ่มต้น แต่เมื่อใดก็ตามที่คุณอ้างอิงคลาสคุณต้องรวมอาร์กิวเมนต์ทั้งหมดไว้จนกว่าจะมีการกำหนดนิยาม
เช่น. มาใช้std::vector
โดยไม่รวมมัน (อาร์กิวเมนต์ที่สองของstd::vector
ถูกกำหนดด้วยค่าเริ่มต้น):
namespace std
{
template<typename, typename>
class vector;
}
#include <iostream>
template <typename S, typename T>
void Foo (const std::vector<S,T> & vector)
{
std::cout << "do vector stuff, eg., display size = "
<< vector.size() << std::endl;
}
template <typename T>
void Foo (const T & t)
{
std::cout << "do non-vector stuff..." << std::endl;
}
จากนั้นเราสามารถใช้มันได้โดยไม่ต้องรวมเวกเตอร์เช่น:
int main ()
{
Foo(3);
}
... หรือสามารถใช้กับ std::vector
เช่น:
#include <vector>
// Now the compiler understands how to handle
// std::vector with one argument
// (making use of its default argument)
int main ()
{
Foo(std::vector<int>(3));
}
ฉันยังไม่ได้ตรวจสอบมาตรฐาน แต่งานนี้บนclang
/ gcc
กับ-std=c++98
ขึ้นไป-std=c++17
ดังนั้นถ้ามันไม่ได้เป็นอย่างเป็นทางการมาตรฐานแล้วมันดูเหมือนจะเป็นอย่างไม่เป็นทางการเพื่อให้
Foo<> foo;
บางทีคุณอาจจะลืมวงเล็บมุมที่ว่างเปล่า