Online Book Reader

Home Category

Professional C__ - Marc Gregoire [361]

By Root 1492 0
and so on. The standard defines several helper classes for this. The following list gives a few examples of the available type traits-related classes in the C++11 standard. See the Reference resource on the website (www.wrox.com) for a complete list.

Primary type categories is_void

is_integral

is_floating_point

is_pointer

. . .

Composited type categories is_reference

is_object

is_scalar

. . .

Type properties is_const

is_literal_type

is_polymorphic

is_unsigned

is_constructible

is_copy_constructible

is_move_constructible

is_assignable

. . .

Type relations is_same

is_base_of

is_convertible

const-volatile modifications remove_const

add_const

. . .

Reference modifications remove_reference

add_lvalue_reference

add_rvalue_reference

Sign modifications make_signed

make_unsigned

Other transformations enable_if

conditional

. . .

Type traits is a pretty advanced and complicated feature. By just looking at the preceding list, which is already a shortened version of the list in the standard itself, it is clear that this book cannot explain all details about type traits. This section explains just a couple of use cases to show you how type traits could be used.

Using Type Categories

Type traits requires the header file. Before an example can be given for a template using type traits, you first need to know a bit more on how classes like is_integral work.

The standard defines an integral_constant class that looks as follows:

template

struct integral_constant {

static constexpr T value = v;

typedef T value_type;

typedef integral_constant type;

constexpr operator value_type() { return value; }

};

typedef integral_constant true_type;

typedef integral_constant false_type;

What this defines is two types: true_type and false_type. When you call true_type::value you will get the value true and when you call false_type::value you will get the value false. You can also call true_type::type, which will return the type of true_type. The same holds for false_type. Classes like is_integral and is_class inherit from integral_constant. For example, is_integral can be specialized for type bool as follows:

template<> struct is_integral : true_type { };

This allows you to write is_integral::value, which will return the value true. Note that you don’t need to write these specializations yourself; they are part of the standard library.

The following code shows the simplest example of how type categories can be used:

if (is_integral::value) {

cout << "int is integral" << endl;

} else {

cout << "int is not integral" << endl;

}

if (is_class::value) {

cout << "string is a class" << endl;

} else {

cout << "string is not a class" << endl;

}

Code snippet from TypeTraits\basic.cpp

This example is using is_integral to check whether int is an integral type or not, and uses is_class to check whether string is a class or not. The output is as follows:

int is integral

string is a class

Of course, you will likely never use type traits in this way. They become more useful in combination with templates to generate code based on some properties of a type. The following template example demonstrates this:

template

void process_helper(const T& t, true_type)

{

cout << t << " is an integral type." << endl;

}

template

void process_helper(const T& t, false_type)

{

cout << t << " is a non-integral type." << endl;

}

template

void process(const T& t)

{

process_helper(t, typename is_integral::type());

}

int main()

{

process(123);

process(2.2);

process(string("Test"));

return 0;

}

Code snippet from TypeTraits\is_integral.cpp

The output of this example is as follows:

123 is an integral type.

2.2 is a non-integral type.

Test is a non-integral type.

The preceding code defines an overloaded function template process_helper() that accepts a type as template argument. The first argument to this function is a value and the second argument is

Return Main Page Previous Page Next Page

®Online Book Reader