Partial template specialization based on signed-ness of integer type?
You can use enable_if
with the is_unsigned
type trait:
template <typename T>
typename std::enable_if<std::is_unsigned<T>::value, bool>::type f(T n)
{
return n <= 100;
}
template <typename T>
typename std::enable_if<!std::is_unsigned<T>::value, bool>::type f(T n)
{
return n >= 0 && n <= 100;
}
You can find enable_if
and is_unsigned
in the std
or std::tr1
namespaces if your compiler supports C++0x or TR1, respectively. Otherwise, Boost has an implementation of the type traits library, Boost.TypeTraits. The boost implementation of enable_if
is a little different; boost::enable_if_c
is similar to the TR1 and C++0x enable_if
.
Extract signed-ness of template type?
Pre-C++11 you can use this implementation of std::conditional
:
template<bool B, class T, class F>
struct conditional { typedef T type; };
template<class T, class F>
struct conditional<false, T, F> { typedef F type; };
Then we can write a struct to extract the signedness of a type:
template <typename T>
struct signedness {
typedef typename conditional<T(-1)<T(0),int,unsigned>::type type;
};
Then just declare base
as being that type:
std::string IntToString(T a,
typename signedness<T>::type base = 10){
Get the signed/unsigned variant of an integer template parameter without explicit traits
The answer is in <type_traits>
For determining the signed-ness of a type use std::is_signed
and std::is_unsigned
.
For adding/removing signed-ness, there is std::make_signed
and std::make_unsigned
.
signed/unsigned trait programming
In this case, there's a few ways to go about it, but my favorite for cases where there's a limited number of variants (e.g., a boolean or two saying which way it should behave), partial specialization of a template is usually the best way to go:
// Original implementation with default boolean for the variation type
template <typename T, bool is_unsigned = std::is_unsigned<T>::value>
class FXP {
// default implementation here
};
Your next step is to then provide a partial specialization that takes the typename T, but only works for a specific variant of the template parameters (e.g. true
or false
).
template <typename T>
class FXP<T, false> {
// partial specialization when is_unsigned becomes false
};
template <typename T>
class FXP<T, true> {
// partial specialization when is_unsigned becomes true
};
In this case, if you write a default implementation, you only need to make a specialization for the case that's non-default (like the true case).
Here's an example, where the default case gets overridden by a specialized template parameter:
http://coliru.stacked-crooked.com/a/bc761b7b44b0d452
Note that this is better only for smaller cases. If you need complex tests, you're better off using std::enable_if and some more complicated template parameters (like in DyP's answer).
Good luck!
Get rid of warning in templated method due to unsignedness
With Tag dispatching and traits:
template <typename T>
bool is_negative(T t, std::true_type)
{
return t < 0;
}
template <typename T>
bool is_negative(T t, std::false_type)
{
return false;
}
template<class IntegralType>
void randomFunction(IntegralType t)
{
...
if (is_negative(t, std::is_signed<IntegralType>::type())
...
}
std::is_signed
can be implemented in C++03.
can template alias be used for partial specialization?
The code is perfectly fine in C++11. The Clang's warning can be ignored.
Adding more types to template specialization
From the std::array
C++ documentation:
template<
class T,
std::size_t N
> struct array;
So, you need
template<std::size_t I> struct meta<std::array<double, I>> {
static constexpr const char* class_name = "double[]";
static const char* get_name() { return class_name; }
};
Because int
and std::size_t
are two different types (having different signed-ness), the partial template specialization won't match. Changing int
to size_t
works.
In summary: Read the documentation.
Related Topics
C and C++ Functions Without a Return Statement
How to Convert a Tchar Array to Std::String
Adding Header and .Cpp Files in a Project Built with Cmake
Msvc Equivalent of _Attribute_ ((Warn_Unused_Result))
Rotating a 2D Pixel Array by 90 Degrees
0Xc0000005: Access Violation Reading Location 0X00000000
How Is Push_Back Implemented in Stl Vector
How to Compile a C++ Code in Gcc (G++) to See The Name Mangling on Overloaded Functions
Opencv 2.4.2 Calcopticalflowpyrlk Doesn't Find Any Points
How to Resize an Image to a Specific Size in Opencv
How to Implement a Video Widget in Qt That Builds Upon Gstreamer
C++ Is It Necessary to Delete Dynamically Allocated Objects at the End of the Main Scope
Linux C++: Does a Return from Main() Cause a Multithreaded App to Terminate
Conversion from 'Myitem*' to Non-Scalar Type 'Myitem' Requested
What Happens to an Stl Iterator After Erasing It in VS, Unix/Linux