[英]Template specialization for multiple types
標題有點含糊。
假設我有一個模板定義為:
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 問題。
一種可能性是一次為多種類型專門化一個類模板:
// 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);
}
您需要remap
特征來簡單地從輸入類型映射到輸出類型,並將您的foo<T>(int)
接口函數委托給foo_implementation<remap<T>::type>(int)
實現。 IE:
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);
}
也就是說,定義foo_char
、 foo_int
和foo_short
並從客戶端代碼中調用正確的可能實際上更簡單。 foo<X>()
在語法上與foo_X()
沒有太大不同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.