2013-07-13 42 views
5

Tiêu đề có một chút mơ hồ.Chuyên môn về mẫu cho nhiều loại

phép nói rằng tôi có một mẫu định nghĩa là:

template < typename T > 
void foo (int x) ; 
template <> 
void foo<char> (int x) ; 
template <> 
void foo<unsigned char> (int x) ; 
template <> 
void foo<short> (int x) ; 
... 

Bên trong cả hai foo<signed>()foo<unsigned>() thực hiện chính xác những điều tương tự. Yêu cầu duy nhất là T là loại 8 bit.

Tôi có thể làm điều này bằng cách tạo một mẫu khác để nhập xác định loại tiêu chuẩn dựa trên kích thước.

template < typename T, size_t N = sizeof(T) > struct remap ; 
template < typename T, size_t > struct remap<1> 
{ 
    typedef unsigned char value; 
} 
... 

Lưu ý, mẫu chức năng không thể có thông số mặc định. Giải pháp này chỉ di chuyển vấn đề đến một mẫu khác và cũng giới thiệu một vấn đề nếu ai đó cố gắng truyền một kiểu cấu trúc làm tham số.

Cách thanh lịch nhất để giải quyết vấn đề này mà không lặp lại các khai báo hàm đó là gì?

Đây không phải là câu hỏi C++ 11.

+0

Bạn đã thử sử dụng enable_if để kiểm tra kích thước của loại? Tôi giả sử bạn đang làm điều tương tự cho tất cả các loại có sẵn cùng kích thước? – Borgleader

+0

@Borgleader enable_if là C++ 11 – Twifty

+2

SFINAE và ['enable_if'] (http://en.cppreference.com/w/cpp/types/enable_if) có thể được triển khai trong C++ 03. – dyp

Trả lời

4

Bạn cần có đặc tính remap để chỉ ánh xạ từ kiểu đầu vào sang loại đầu ra và có giao diện chức năng foo<T>(int) ủy quyền cho foo_implementation<remap<T>::type>(int) thực hiện. tức là:

template <typename T> 
struct remap { 
    // Default: Output type is the same as input type. 
    typedef T type; 
}; 

template <> 
struct remap<char> { 
    typedef unsigned char type; 
}; 

template <> 
struct remap<signed char> { 
    typedef unsigned char type; 
}; 

template <typename T> 
void foo_impl(int x); 

template <> 
void foo_impl<unsigned char>(int x) { 
    std::cout << "foo_impl<unsigned char>(" << x << ") called\n"; 
} 

template <typename T> 
void foo(int x) { 
    foo_impl<typename remap<T>::type>(x); 
} 

See it live at ideone.com.

Điều đó nói rằng, có thể thực tế đơn giản hơn để xác định foo_char, foo_intfoo_short và chỉ cần gọi đúng từ mã máy khách. foo<X>() không khác biệt nhiều về cú pháp từ foo_X().

7

Một khả năng là chuyên một lớp mẫu cho nhiều loại cùng một lúc:

// from: http://en.cppreference.com/w/cpp/types/enable_if 
    template<bool B, class T = void> 
    struct enable_if {}; 

    template<class T> 
    struct enable_if<true, T> { typedef T type; }; 

template < typename A, typename B > 
struct is_same 
{ 
    static const bool value = false; 
}; 
template < typename A > 
struct is_same<A, A> 
{ 
    static const bool value = true; 
}; 


template < typename T, typename dummy = T > 
struct remap; 

template < typename T > 
struct remap 
< 
    T, 
    typename enable_if< is_same<T, unsigned char>::value 
         || is_same<T, signed char>::value, T >::type 
> 
{ 
    void foo(int); 
}; 


int main() 
{ 
    remap<signed char> s; 
    s.foo(42); 
} 

Một khả năng khác là để chuyên một lớp mẫu cho các hạng mục của các loại (loại đặc điểm):

#include <cstddef> 

template < typename T > 
struct is_integer 
{ 
    static const bool value = false; 
}; 
template<> struct is_integer<signed char> { static const bool value = true; }; 
template<> struct is_integer<unsigned char> { static const bool value = true; }; 


template < typename T, typename dummy = T, std::size_t S = sizeof(T) > 
struct remap; 

template < typename T > 
struct remap 
< 
    T 
    , typename enable_if<is_integer<T>::value, T>::type 
    , 1 // assuming your byte has 8 bits 
> 
{ 
    void foo(int); 
}; 


int main() 
{ 
    remap<signed char> s; 
    s.foo(42); 
} 
+0

Tôi chỉ muốn lưu ý có một tiêu chuẩn :: enable_if, vì vậy bạn không cần phải tự xác định nó. Xem [tại đây] (http://en.cppreference.com/w/cpp/types/enable_if). – leetNightshade

+1

@leetNightshade 'enable_if' đã được thêm vào C++ 11; câu hỏi đặt mục tiêu C++ 03 (ngoài ra, tôi đã thêm một chú thích vào OP với cùng một liên kết;) – dyp

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