Reputation: 75
I would like to specialize template by group of types and also by extra definition for some specific simple types. Is it in C++11 and boost 1.60 possible? Following pseudocode illustrates my intention:
template <typename T> // Universal definition
struct convert
{ ... }
template <> /* Definition for integral types like defined by std::type_traits */
struct convert<integral_types>
{ ... }
template <> /* Definition for floating point types like defined by type_traits */
struct convert<floating_types>
{ ... }
template <> /* Exception from integral types - specific definition */
struct convert<char>
{ ... }
I think this could be solved by tag dispatcher, but I'm not sure if it's best solution. Another option is enable_if
, combined with is_integral
(and similar groups) , but simple char
type is problem...
Upvotes: 5
Views: 632
Reputation: 1295
Here is an alternative solution without using std::enable_if_t
:
// g++ -Wall -std=c++11 -o typetraitstest typetraitstest.C
#include <iostream>
#include <type_traits>
#include <cstdint>
template <typename T, bool isFloatingPoint, bool isSigned>
struct _Numeric;
template <typename T>
struct _Numeric<T, true, true>
{
void doit() { std::cout << "FloatingPoint " << sizeof (T) << " byte\n"; }
};
template <typename T>
struct _Numeric<T, false, true>
{
void doit() { std::cout << "SignedInt " << sizeof(T) << " byte\n"; }
};
template <typename T>
struct _Numeric<T, false, false>
{
void doit() { std::cout << "UnsignedInt " << sizeof(T) << " byte\n"; }
};
template <>
struct _Numeric<char, false, true>
{
void doit() { std::cout << "special case char\n"; }
};
template <typename T>
struct Numeric :
_Numeric<T, std::is_floating_point<T>::value, std::is_signed<T>::value>
{};
int
main()
{
Numeric<float> f;
Numeric<int32_t> i32;
Numeric<uint64_t> u64;
Numeric<char> c;
f.doit();
i32.doit();
u64.doit();
c.doit();
return 0;
}
This is the output (note that char
seems to be signed):
% ./typetraitstest
FloatingPoint 4 byte
SignedInt 4 byte
UnsignedInt 8 byte
special case char
Upvotes: 0
Reputation: 217283
You may do something like:
template <typename T, typename Enabler = void> // Universal definition
struct convert
{ ... };
template <typename T> /* Definition for integral types like defined by std::type_traits */
struct convert<T, std::enable_if_t<std::is_integral<T>::value>>
{ ... };
template <> /* Exception from integral types - specific definition */
struct convert<char, void>
{ ... };
Upvotes: 9