Thursday, 6 June 2013

C++ 11 ( some important features ) static_assert and type_traits

Hello friends,
            Welcome you all in the C++ 11 Part5. In the Part4 we have discussed about lambda function.

In this part we will learn about static_assert and type_traits.

static_assert:
                       
            static_assert performs compile time assertion checking. If the assertion is false, the complier shows the specified error message.

syntax: static_assert(constant_expression, error_message)

constant_expression must be a constant expression that can be converted to bool.
Error_message must be a string literal. You can give the error message what you want to display.


Let’s see how we can use static_assert in our c++ code.
//author: shobhit upadhyaya

template < class T, size_t length >
class String
{
   static_assert(length < 100, "length is too big");
   T str_data[length];
};

int main()
{
   String< int, 101 > a1;
   String< int, 90 > a2;
   return 0;
}

The above code gives you the following error at compile time, because in the static_assert we have a condition string length should be less than 100. But we are trying to give a string length greater than 100.

error C2338: length is too big
  : see reference to class template instantiation 'String<int,101>' being compiled


Static_assert becomes more powerful when used together with the type_traits.
<type_traits> header files provide various classes that give information about types at compile time.

<type_traits> header is categorized into three classes:
            Helper classes: for creating compile time constants.
            Type traits: to get type information at compile time.
            Type transformation: for getting new types by applying specific transformations to existing types.


Let’s see the example how type_traits can help us:-

//author: shobhit upadhyaya

#include 
#include 
using namespace std;

template < class T1, class T2 >
auto mul(T1 a, T2 b) -> decltype(a * b) 
{
  static_assert(is_integral::value,"T1, please input integral value");
  static_assert(is_integral::value,"T2, please input integral value");

   return a * b;
};

int main()
{
   mul(1,3.14);
   mul(1,5);    
   return 0;
}
//


The above code gives the following error at compile time. Because in the static_assert we are using a type_trait is_integral. is_integral checks the type and return false if it is not an integral type. But in our code we are trying to pass a floating point value.

: error C2338: T2, please input integral value
 : see reference to function template instantiation 'T2 mul<int,double>(T1,T2)' being compiled
        with
        [
            T2=double
,            T1=int
        ]


Following are some example of type_traits:-
1.     is_array :-
This check type is an array or not. If not returns false.
2.     is_class:-
This check type is a class or not. If not returns false.
3.     is_enum:-
This check type is an enum or not. If not returns false.
4.     is_floating_point:-
This checks type is a floating point or not. If not returns false.
5.     is_function:-
This checks type is a function or not. If not returns false.
6.     is_integral:-
This checks type is an integral or not. If not returns false.
7.     is_lvalue_reference:-
This checks type is lvalue_reference or not. If not returns false.
8.     is_member_function_pointer:-
This checks type is a pointer to member function or not. If not returns false.
9.     is_member_object_pointer:-
This checks type is a pointer to member object or not. If not returns false.
10.  is_pointer:-
This checks type is a pointer or not. If not returns false.
11.  is_rvalue_reference:-
This checks type is an rvalue reference or not. If not returns false.
12.  is_union:-
This checks type is a union or not. If not returns false.
13.  is_void:-
This checks type is a void or not. If not returns false.

            There are so many others type_traits that I have not covered here. With the help of all there type_traits we can improve the static_assert.






Feel free to give your valuable comments and feedback.
Do not forgot to share J

1 comment:

  1. I think your angle braces got swallowed; is_integral::value needs to specify a type.

    ReplyDelete