Class template for numeric types
You can use the std::is_arithmetic
type trait. If you want to only enable instantiation of a class with such a type, use it in conjunction with std::enable_if
:
#include <type_traits>
template<
typename T, //real type
typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type
> struct S{};
int main() {
S<int> s; //compiles
S<char*> s; //doesn't compile
}
For a version of enable_if
that's easier to use, and a free addition of disable_if
, I highly recommend reading this wonderful article on the matter.
In C++, the technique described above has a name called "Substitution Failure Is Not An Error" (most use the acronym SFINAE). You can read more about this C++ technique on wikipedia or cppreference.com.
As of C++20, concepts make this much easier and don't spoil the interface:
#include <concepts>
template<typename T>
concept arithmetic = std::integral<T> or std::floating_point<T>;
template<typename T>
requires arithmetic<T>
struct S{};
// Shorthand: template<arithmetic T> struct S {};
Do note that there are many user types meant to be used arithmetically as well, though, so a more general concept that covers the operations you're looking for instead of the types you're looking for would be preferable in a generic interface.
C++ template for numeric types
There's probably better ways of doing this, but the simplest way to me is to just slap the enable_if
onto the return type:
template<typename T, typename ... Types>
typename std::enable_if<
std::is_arithmetic<T>::value
>::type
myFct(T arg1, Types ... rest) { /*do numeric stuff*/ }
template<typename T, typename ... Types>
typename std::enable_if<
!std::is_arithmetic<T>::value
>::type
myFct(T arg1, Types ... rest) { /*do non-numeric stuff*/ }
This gets very unwieldy once you have more than just two mutually exclusive options, but this will definitely work.
Template friendly string to numeric in C++
Why there are no template functions something like:
C++17 has such generic string to number function, but named differently. They went with std::from_chars
, which is overloaded for all numeric types.
As you can see, the first overload is taking any integer type as an output parameter and will assign the value to it if possible.
It can be used like this:
template<typename Numeric>
void stuff(std::string_view s) {
auto value = Numeric{};
auto [ptr, error] = std::from_chars(s.data(), s.data() + s.size(), value);
if (error != std::errc{}) {
// error with the conversion
} else {
// conversion successful, do stuff with value
}
}
As you can see, it can work in generic context.
Template Function Specialization for Integer Types
Use SFINAE
// For all types except integral types:
template<typename T>
typename std::enable_if<!std::is_integral<T>::value>::type f(T t)
{
// ...
}
// For integral types only:
template<typename T>
typename std::enable_if<std::is_integral<T>::value>::type f(T t)
{
// ...
}
Note that you will have to include the full std::enable_if
return value even for the declaration.
C++17 update:
// For all types except integral types:
template<typename T>
std::enable_if_t<!std::is_integral_v<T>> f(T t)
{
// ...
}
// For integral types only:
template<typename T>
std::enable_if_t<std::is_integral_v<T>> f(T t)
{
// ...
}
C++ Limit template type to numbers
What you need std::is_arithmetic to constrain the template type to a arithmetic types (integral or floating point). You can use it like
template <typename T, typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr>
void Deposit(T t) {...}
How to wrap a C function library that works with different numeric types into a C++ template class
I'm not sure I've caught exactly the problem.
Something like that using partial specialization could solve?
template<class T>
class Fwd { }
template<>
class Fwd<double> {
void execute(std::pair<double, double> pp) {
fftw_execute(pp);
}
}
template<>
class Fwd<float> {
void execute(std::pair<float, float> pp) {
fftwf_execute(pp);
}
}
// and so on...
How do I refer to a class with multiple template types by only one of the types?
It seems like you are looking for CTAD (class template argument deduction). It only works when the caller does not specify any template argument, hence a layer of indirection has to be added:
template <typename T>
struct ShapeWrap {
template <typename U,typename V>
struct Shape {
T value;
U input;
V input2;
Shape(const U& u,const V& v) : input(u),input2(v) {}
};
};
Caller can now call:
auto s = ShapeWrap<int>::Shape(1.0,0.1f);
To instantiate ShapeWrap<int>::Shape<double,float>
.
Alternatively via template argument deduction of a function template:
template <typename T, typename U,typename V>
struct Shape {
T value;
U input;
V input2;
Shape(const U& u,const V& v) : input(u),input2(v) {}
};
template <typename T,typename U,typename V>
Shape<T,U,V> make_shape(const U& u, const V& v) {
return {u,v};
}
int main() {
auto s = make_shape<int>(1.0,0.1f);
}
Partial class template specialisation for multiple types
I suppose you can use a boolean default value, like in foo
struct in the following example
#include <iostream>
template <typename>
struct isSpecialType
{ static constexpr bool value { false }; };
template <>
struct isSpecialType<int>
{ static constexpr bool value { true }; };
template <>
struct isSpecialType<double>
{ static constexpr bool value { true }; };
template <typename T, bool = isSpecialType<T>::value>
struct foo;
template <typename T>
struct foo<T, true>
{ static constexpr bool value { true }; };
template <typename T>
struct foo<T, false>
{ static constexpr bool value { false }; };
int main()
{
std::cout << "- void value: " << foo<void>::value << std::endl;
std::cout << "- bool value: " << foo<bool>::value << std::endl;
std::cout << "- int value: " << foo<int>::value << std::endl;
std::cout << "- double value: " << foo<double>::value << std::endl;
}
The idea is define a sort of type traits (isSpecialType
) to choose the selected types (int
and double
, in your example) with a booleand value that is false
in the generic implementation and true
in the specializations.
template <typename>
struct isSpecialType
{ static constexpr bool value { false }; };
template <>
struct isSpecialType<int>
{ static constexpr bool value { true }; };
template <>
struct isSpecialType<double>
{ static constexpr bool value { true }; };
Next you have to declare the foo
struct (class Vec
, in your question) with a supplemental bool
template value with the isSpecialType<T>::value
default value
template <typename T, bool = isSpecialType<T>::value>
struct foo;
Last, you have to implement two partially specialized version of foo
: the first one with the boolean true
value
template <typename T>
struct foo<T, true>
{ static constexpr bool value { true }; };
corresponding to the specialized version of your Vec
; the one with the false
boolean value
template <typename T>
struct foo<T, false>
{ static constexpr bool value { false }; };
corresponding to the generic version of your Vec
.
Another point: my example is C++11 or newer code; if you want a C++98 version, you have only to define the bool
values as const
(instead constexpr
) and initialize they whit the C++98 style; I mean
static bool const bool value = true;
instead of
static constexpr bool value { true };
Related Topics
Undefined Symbols for Architecture X86_64 - Mavericks (Yosemite, El Capitan...)
C++ Streams Confusion: Istreambuf_Iterator VS Istream_Iterator
How to "Reveal in Finder" or "Show in Explorer" with Qt
Sqlite3_Exec() Callback Function Clarification
How to Count Lines of a File in C++
C++: Pointer to Monomorphic Version of Virtual Member Function
Opencv: How to Visualize a Depth Image
How to Find Longest Common Substring Using C++
"Roll-Back" or Undo Any Manipulators Applied to a Stream Without Knowing What the Manipulators Were
Interpolate from One Color to Another
C++ Stl: Array VS Vector: Raw Element Accessing Performance
Maximum Number of Parameters in Function Declaration
Forward Declaration VS Include
Type Erasure in C++: How Boost::Shared_Ptr and Boost::Function Work