Use template type via static_assert

I am trying to understand the usefulness of static_assert , and I want to know if this can help me in ensuring the execution of the design, and if so, how.

I have a generic template class that hides its own implementation inside another template class, which partially specializes based on the size of the template type. Here is a brief description of this project:

 template <class T, size_t S = sizeof(T)> struct Helper; template <class T> struct Helper<T, sizeof(long)> { static T bar(); }; // ... other specializations ... template <class T> class Foo { public: T bar() { return Helper<T>::bar(); } }; 

Foo is only supported if size T supported by the Helper specialization. For example, Foo<long> and Foo<unsigned long> supported. However, suppose the user is trying to build a Foo<bool> . This usually causes errors because the Helper specialization for bool not defined, which is the intended behavior.

Can static_assert be used in this project to provide the user with more useful errors?

In addition, I would also like to limit the user to a specific type, although the size may be correct. For example, Foo<float> not allowed. Right now, the only way I know to provide this is with a bold comment in the documentation. :)

+7
c ++ templates static-assert template-specialization
source share
3 answers

I decided to better solve this problem by combining the answers and comments here.

I can define a static type check like this:

 template <class A, class B> struct CheckTypes { static const bool value = false; }; template <class A> struct CheckTypes<A, A> { static const bool value = true; }; 

Not sure if such a structure already exists in the standard library. Anyway, then in Foo , I can check the types and sizes using:

 static_assert((sizeof(T) == sizeof(long) || sizeof(T) == sizeof(int)) && !CheckTypes<T, float>::value, "Error!"); 
+1
source share

If it can work only to specialize the template class, then the template class defaults to a static statement:

 template <class T, size_t S = sizeof(T)> struct Helper { static_assert(sizeof(T) == -1,"You have to have a sepecialization for Helper!" ); } 

The default template class will be selected only if there is no better specialization, so the statement will be raised.

You can use the same method to prohibit types, but you will need another template parameter that will be used to check static confirmation.

 template <class T, class G = T, size_t S = sizeof(T)> struct Helper { static_assert(sizeof(G) == -1,"You have to have a sepecialization for Helper!" ); } template <class G> struct Helper<float,G> { static_assert(sizeof(G) == -1,"You can't use float !" ); } template <> struct Helper<int> { //This is a good specialization }; 

Then you can try it with these variables:

 Helper<bool> a; //"You have to have a sepecialization for Helper!" Helper<float> b; //"You can't use float !" Helper<int> c; //compiles OK 
+13
source share

http://en.cppreference.com/w/cpp/header/type_traits

std::is_base_of and std::is_convertible can help with your first problem, and the second -

static_assert(!std::is_same<float,T>(),"type can't be float");

hope this helps someone else who stumbled upon this question, believing that the OP probably found the answer within 4 years since being asked :)

+3
source share

All Articles