Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I restrict a template class to certain built-in types?

This issue has been discussed a few times but all the solutions I have found either didn't work or were based on boost's static assert. My problem is simple. I have a class, and I only want to allow real types (double and float). I want a compile-time error if I try to instantiate the class with a type other than float or double. I am using Visual C++ 11. Here is what I have tried:

template <typename RealType> class A {   // Warning C4346   static_assert(std::is_same<RealType, double>::value || std::is_same<RealType, float>::value); }   template <typename RealType> class A {   // Error C2062: type 'unknown' unexpected   static_assert(decltype(RealType) == double || decltype(RealType) == float); } 

Any ideas? Thanks in advance!

like image 222
quant Avatar asked Jun 07 '13 05:06

quant


People also ask

How will you restrict the template for a specific datatype?

There are ways to restrict the types you can use inside a template you write by using specific typedefs inside your template. This will ensure that the compilation of the template specialisation for a type that does not include that particular typedef will fail, so you can selectively support/not support certain types.

What are non-type parameters for templates?

A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument. A non-type parameter can be any of the following types: An integral type. An enumeration type.

Can a template class have more than one generic data type?

Explanation: The template class can support more than one data type. The only thing is to add all the data types required in a list separated by comma within template specification. 2. Which among the following is the proper syntax for the template class?

What is template type parameter?

A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.


1 Answers

In your first example, static_assert should take a second parameter which would be a string literal, otherwise it's deemed to fail (edit: dropping the the second parameter is legal since C++17). And this second argument cannot be defaulted.

Your second example is incorrect for several reasons:

  • decltype is meant to be used on an expression, not on a type.
  • You simply cannot compare types with ==, the correct way to do this is what you try in your first attempt with std::is_same.

So, the right way to do what you are trying to achieve is:

#include <type_traits>  template <typename RealType> class A {   static_assert(std::is_same<RealType, double>::value || std::is_same<RealType, float>::value,                 "some meaningful error message"); }; 

Moreover, I bet you are trying to constrict your template to floating points values. In order to do this, you can use the trait std::is_floating_point:

#include <type_traits>  template <typename RealType> class A {   static_assert(std::is_floating_point<RealType>::value,                 "class A can only be instantiated with floating point types"); }; 

And as a bonus, take this online example.

like image 60
Morwenn Avatar answered Oct 11 '22 03:10

Morwenn