Tôi đang cố gắng viết mã sử dụng thành phần typedef của đối số mẫu, nhưng muốn cung cấp loại mặc định nếu đối số mẫu không có typedef đó. Một ví dụ đơn giản mà tôi đã thử là:Chuyên môn mẫu để sử dụng loại mặc định nếu thành viên nhóm typedef không tồn tại
struct DefaultType { DefaultType() { printf("Default "); } };
struct NonDefaultType { NonDefaultType() { printf("NonDefault "); } };
struct A {};
struct B { typedef NonDefaultType Type; };
template<typename T, typename Enable = void> struct Get_Type {
typedef DefaultType Type;
};
template<typename T> struct Get_Type< T, typename T::Type > {
typedef typename T::Type Type;
};
int main()
{
Get_Type<A>::Type test1;
Get_Type<B>::Type test2;
}
Tôi hy vọng điều này sẽ in "Mặc định không mặc định", nhưng thay vào đó sẽ in "Mặc định mặc định". Kỳ vọng của tôi là dòng thứ hai trong main() phải khớp với phiên bản đặc biệt của Get_Type, vì B :: Type tồn tại. Tuy nhiên, điều này không xảy ra.
Có ai có thể giải thích những gì đang diễn ra ở đây và cách khắc phục hoặc cách khác để đạt được mục tiêu tương tự?
Cảm ơn bạn.
Chỉnh sửa:
Georg đã đưa ra một phương pháp thay thế, nhưng tôi vẫn tò mò về lý do tại sao điều này không hiệu quả. Theo các các tăng enable_if tài liệu, một cách để chuyên một mẫu với nhiều loại khác nhau là như vậy:
template <class T, class Enable = void>
class A { ... };
template <class T>
class A<T, typename enable_if<is_integral<T> >::type> { ... };
template <class T>
class A<T, typename enable_if<is_float<T> >::type> { ... };
này hoạt động vì enable_if < đúng> đã gõ như một typedef, nhưng enable_if < false> không.
Tôi không hiểu điều này khác với phiên bản của tôi như thế nào, thay vì sử dụng enable_if tôi chỉ sử dụng T :: Loại trực tiếp. Nếu T :: Loại tồn tại sẽ không giống như enable_if < true> :: nhập vào ví dụ trên và khiến chuyên môn được chọn? Và nếu T :: Type không tồn tại, nó sẽ không giống như enable_if < false> :: type không tồn tại và gây ra phiên bản mặc định được chọn trong ví dụ trên?
Uh .. mục tiêu là gì? –
Mục tiêu là Get_Type :: Loại sẽ là T :: Nhập nếu nó tồn tại hoặc DefaultType nếu nó không tồn tại. –
Frank