5

Tôi muốn viết như sau:Tôi nên làm gì thay vì chuyên môn hóa một phần các mẫu chức năng?

template <typename S, typename T> void foo() { 
    /* code for the general case */ 
} 

template <typename T> void foo<MySType,T>() { 
    /* partially specialized code - for any kind of T, but when S is MySType */ 
} 

hoặc, trong trường hợp khác, như sau:

template <typename S, typename T> void bar(const S& a, const T& b) { 
    /* code for the general case */ 
} 

template <typename T> void bar<MySType,T>(const MySType& a, const T& b) { 
    /* partially specialized code - for any kind of T, but when S is MySType */ 
} 

C++ (11) sẽ không cho phép tôi làm điều này.

Bây giờ, tôi đã đọc this question and its answers; giả sử tôi mua giải thích lý do tại sao chúng tôi không có chuyên môn hóa từng phần (hoặc chỉ giả định rằng tôi đang sống trong thực tế và thực sự muốn viết mã). Vâng, những gì làm Tôi làm, thay vì?

Tôi thực sự không muốn bọc các chức năng này trong một lớp trừ khi đó hoàn toàn là phương sách cuối cùng của tôi.

+0

thành thật tôi càng lao vào C++ 11 và C++ nói chung, tôi càng nghĩ rằng "mẫu chuyên môn" là một trình độ khủng khiếp cho những gì đang xảy ra . Không có điều gì như "chuyên môn mẫu" – user2485710

+0

@ user2485710: Tôi xin lỗi, tôi không hiểu ... bạn có thể xây dựng được không? Hoặc liên kết đến nơi bạn đã tranh cãi điều này ở độ dài hơn? – einpoklum

+1

Không chỉ là chuyên môn về mẫu một thứ, nó là một máy hoàn thiện Turing. Nó có thể khiến bạn phát điên. – Potatoswatter

Trả lời

3

Một lựa chọn khác là sử dụng một mẫu lớp helper, nơi bạn có thể làm chuyên môn hóa một phần, và giấu nó bằng cách sử dụng chức năng bao bọc mà không cần phải được chuyên phần bản thân:

#include <iostream> 

template<typename S, typename T> 
struct foo_helper { 
    void foo() { 
     std::cout << "general func" << std::endl;   
    } 
}; 

struct MyType {}; 

template <typename T> 
struct foo_helper <MyType,T> { 
    void foo() { 
     std::cout << "partially specialized code - for any kind of T, but when S is MyType" << std::endl; 
    } 
}; 

template<typename S, typename T> 
void foo() { 
    foo_helper<S, T>().foo(); 
} 

int main() { 
    foo<int, int>(); 
    foo<int, double>(); 
    foo<MyType, long>(); 
} 

Đây là C++ 98/03 hợp lệ.

+0

Tôi có thể tự động hóa bằng cách nào đó/macro hóa việc sử dụng cấu trúc trợ giúp không? – einpoklum

5

Quá tải! Quá tải là vượt trội trong mọi cách để chuyên môn hóa. Một phần của độ phân giải quá tải là chọn quá tải chuyên biệt nhất. Chỉ cần khai báo các "chuyên ngành" là quá tải và nó sẽ hoạt động nếu chuyên môn hóa một phần sẽ có. Tuy nhiên,

Tránh các đối số mẫu rõ ràng. Thay vào đó, bạn có thể sử dụng tính năng gửi thẻ.

template< typename t > 
struct tag {}; 

template <typename S, typename T> foo(tag<S>, tag<T>) { 
    /* code for the general case */ 
} 

template <typename T> foo(tag<MyType>, tag<T>) { 
    /* partially specialized code - for any kind of T, but when S is MyType */ 
} 

Vì các thẻ trống và được truyền theo giá trị, đóng góp của chúng vào chi phí cuộc gọi chức năng có thể bị loại bỏ bởi trình biên dịch.

+0

Ví dụ của OP được xây dựng kém (thiếu kiểu trả về, vv), nhưng mang lại một sự thay đổi thú vị. Chủ yếu, làm thế nào để bạn quá tải một cái gì đó mà có * không có tham số *? – WhozCraig

+0

@WhozCraig Xem cập nhật – Potatoswatter

+0

+1 Tôi sắp đề xuất đăng tag-dispatch = P – WhozCraig

2

Bạn có thể một phần chuyên biệt hoá một cấu trúc helper:

#include <iostream> 

namespace Detail { 
    template <typename S, typename T> 
    struct Foo { 
     static void apply() { 
      std::cout << "general case\n"; 
     } 
    }; 
    template <typename T> 
    struct Foo<int, T> { 
     static void apply() { 
      std::cout << "specialized code\n"; 
     } 
    }; 
} 

template <typename S, typename T> 
void foo() { 
    Detail::Foo<S, T>::apply(); 
} 

int main() 
{ 
    foo<double, double>(); 
    foo<int, double>(); 
    return 0; 
} 
+0

Điều này có thể được tự động/sắp xếp hợp lý bằng cách nào đó, vì vậy mà tôi không phải luôn luôn viết một cách rõ ràng trong không gian tên, các cấu trúc và cetera? – einpoklum

Các vấn đề liên quan