2013-07-13 173 views
5

標題有點模棱兩可。多種類型的模板專業化

可以說我有定義爲一個模板:

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) ; 
... 

內部都foo<signed>()foo<unsigned>()做同樣的事情。唯一的要求是T是一個8位類型。

我可以通過創建另一個模板類型來定義基於大小的標準類型。

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

注意,函數模板不能有默認參數。此解決方案僅將問題重定位到另一個模板,並且如果有人嘗試將結構類型作爲參數傳遞,也會引入問題。

什麼是最優雅的方式來解決這個問題,而不重複這些函數聲明?

這不是C++ 11的問題。

+0

您是否嘗試過使用enable_if來檢查類型的大小?我假設你對所有相同大小的內置類型都做同樣的事情? – Borgleader

+0

@Borgleader enable_if是C++ 11 – Twifty

+2

SFINAE和['enable_if'](http://en.cppreference.com/w/cpp/types/enable_if)也可以在C++ 03中實現。 – dyp

回答

4

您需要您的remap特性才能簡單地將輸入類型映射爲輸出類型,並將您的foo<T>(int)接口函數委託給foo_implementation<remap<T>::type>(int)實現。即:

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

也就是說,定義foo_char,foo_intfoo_short並從客戶端代碼中調用正確的代碼可能會更簡單。 foo<X>()在語法上與foo_X()在語法上沒有太大區別。

7

一種可能性是在一次專門用於多種類型的類模板:

// 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); 
} 

另一種可能性是專門類模板用於類型的類別(類型性狀):

#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

我只是想說明有一個std :: enable_if,所以你不必自己定義它。看[這裏](http://en.cppreference.com/w/cpp/types/enable_if)。 – leetNightshade

+1

@leetNightshade'enable_if'已被添加到C++ 11中;該問題的目標是C++ 03(另外,我已經使用相同的鏈接向OP添加了一條評論;) – dyp