forked from boostorg/mpl
67 lines
1.7 KiB
Plaintext
67 lines
1.7 KiB
Plaintext
<!-- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| section -->
|
|
<section id="if">
|
|
<title>Compile-time if</>
|
|
|
|
<para>
|
|
The most interesting template metaprograms often contain a lot of decision-making code. Some of conditional decisions/behavior can be handled directly by (partial) class template specialization or function overloading <citation><xref linkend="ref.Vel95a"></>, <citation><xref linkend="ref.Ale00"></>, but in general there is a need for a standalone library primitive that would allow one to choose between two types basing on a compile-time expression. In <literal>boost::mpl</> such primitive is called <literal>if_</>:
|
|
</>
|
|
|
|
<programlisting>
|
|
<![CDATA[
|
|
template< typename T >
|
|
struct heap_holder
|
|
{
|
|
// ...
|
|
private:
|
|
boost::scoped_ptr<T> m_object;
|
|
};
|
|
|
|
template< typename T >
|
|
struct stack_holder
|
|
{
|
|
// ...
|
|
private:
|
|
T m_object;
|
|
};
|
|
|
|
template< typename T >
|
|
struct can_be_on_stack
|
|
: mpl::bool_c< (sizeof(T) <= sizeof(double)) >
|
|
{
|
|
};
|
|
|
|
// use 'if_' to choose where to store 'T' member
|
|
template< typename T >
|
|
struct lightweight
|
|
: private mpl::if_<
|
|
can_be_on_stack<T>
|
|
, stack_holder<T>
|
|
, heap_holder<T>
|
|
>::type
|
|
{
|
|
// ...
|
|
};
|
|
]]>
|
|
</>
|
|
|
|
<para>
|
|
Note that the first template parameter of the <literal>if_</> template is a type that should be a model of Integral Constant concept. The library also provides a less generic but sometimes more convenient form that accepts a condition in form of non-type <literal>bool</> template parameter:
|
|
</>
|
|
|
|
<programlisting>
|
|
<![CDATA[
|
|
template< typename T >
|
|
struct lightweight
|
|
: private mpl::if_c<
|
|
(sizeof(T) <= sizeof(double))
|
|
, stack_holder<T>
|
|
, heap_holder<T>
|
|
>::type
|
|
{
|
|
// ...
|
|
};
|
|
]]>
|
|
</>
|
|
|
|
</section>
|