Files
callable_traits/doc/html/index.html
2016-12-10 18:25:20 -06:00

380 lines
46 KiB
HTML

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>CallableTraits</title>
<link rel="stylesheet" href="boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="index.html" title="CallableTraits">
<link rel="next" href="callable_traits/faq.html" title="FAQ">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../boost.png"></td>
<td align="center"><a href="../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav"><a accesskey="n" href="callable_traits/faq.html"><img src="../src/images/next.png" alt="Next"></a></div>
<div lang="en" class="article">
<div class="titlepage">
<div>
<div><h2 class="title">
<a name="callable_traits"></a>CallableTraits</h2></div>
<div><div class="authorgroup"><div class="author"><h3 class="author">
<span class="firstname">Barrett</span> <span class="surname">Adair</span>
</h3></div></div></div>
<div><p class="copyright">Copyright &#169; 2016 Barrett Adair</p></div>
<div><div class="legalnotice">
<a name="callable_traits.legal"></a><p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE.md or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></div>
</div>
<hr>
</div>
<div class="toc">
<p><b>Table of Contents</b></p>
<dl class="toc">
<dt><span class="section"><a href="index.html#callable_traits.introduction">Overview</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="index.html#callable_traits.introduction.motivation">Motivation</a></span></dt>
<dt><span class="section"><a href="index.html#callable_traits.introduction.boost_function_types">Regarding
<code class="literal">Boost.FunctionTypes</code></a></span></dt>
<dt><span class="section"><a href="index.html#callable_traits.introduction.compatibility">Compatibility</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="callable_traits/faq.html">FAQ</a></span></dt>
<dt><span class="section"><a href="callable_traits/reference.html">Reference Documentation</a></span></dt>
<dt><span class="section"><a href="callable_traits/member_qualifier_features.html">Member Qualifier
Features</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="callable_traits/member_qualifier_features.html#callable_traits.member_qualifier_features.ref_add_member_const">add_member_const</a></span></dt>
<dt><span class="section"><a href="callable_traits/member_qualifier_features.html#callable_traits.member_qualifier_features.ref_remove_member_const">remove_member_const</a></span></dt>
<dt><span class="section"><a href="callable_traits/member_qualifier_features.html#callable_traits.member_qualifier_features.ref_add_member_volatile">add_member_volatile</a></span></dt>
<dt><span class="section"><a href="callable_traits/member_qualifier_features.html#callable_traits.member_qualifier_features.ref_remove_member_volatile">remove_member_volatile</a></span></dt>
<dt><span class="section"><a href="callable_traits/member_qualifier_features.html#callable_traits.member_qualifier_features.ref_add_member_cv">add_member_cv</a></span></dt>
<dt><span class="section"><a href="callable_traits/member_qualifier_features.html#callable_traits.member_qualifier_features.ref_remove_member_cv">remove_member_cv</a></span></dt>
<dt><span class="section"><a href="callable_traits/member_qualifier_features.html#callable_traits.member_qualifier_features.ref_add_member_lvalue_reference">add_member_lvalue_reference</a></span></dt>
<dt><span class="section"><a href="callable_traits/member_qualifier_features.html#callable_traits.member_qualifier_features.ref_add_member_rvalue_reference">add_member_rvalue_reference</a></span></dt>
<dt><span class="section"><a href="callable_traits/member_qualifier_features.html#callable_traits.member_qualifier_features.ref_remove_member_reference">remove_member_reference</a></span></dt>
<dt><span class="section"><a href="callable_traits/member_qualifier_features.html#callable_traits.member_qualifier_features.ref_has_member_qualifiers">has_member_qualifiers</a></span></dt>
<dt><span class="section"><a href="callable_traits/member_qualifier_features.html#callable_traits.member_qualifier_features.ref_is_const_member">is_const_member</a></span></dt>
<dt><span class="section"><a href="callable_traits/member_qualifier_features.html#callable_traits.member_qualifier_features.ref_is_volatile_member">is_volatile_member</a></span></dt>
<dt><span class="section"><a href="callable_traits/member_qualifier_features.html#callable_traits.member_qualifier_features.ref_is_cv_member">is_cv_member</a></span></dt>
<dt><span class="section"><a href="callable_traits/member_qualifier_features.html#callable_traits.member_qualifier_features.ref_is_lvalue_reference_member">is_lvalue_reference_member</a></span></dt>
<dt><span class="section"><a href="callable_traits/member_qualifier_features.html#callable_traits.member_qualifier_features.ref_is_rvalue_reference_member">is_rvalue_reference_member</a></span></dt>
<dt><span class="section"><a href="callable_traits/member_qualifier_features.html#callable_traits.member_qualifier_features.ref_is_reference_member">is_reference_member</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="callable_traits/parameter_list_features.html">Parameter List
Features</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="callable_traits/parameter_list_features.html#callable_traits.parameter_list_features.ref_function_type">function_type</a></span></dt>
<dt><span class="section"><a href="callable_traits/parameter_list_features.html#callable_traits.parameter_list_features.ref_args">args</a></span></dt>
<dt><span class="section"><a href="callable_traits/parameter_list_features.html#callable_traits.parameter_list_features.ref_arg_at">arg_at</a></span></dt>
<dt><span class="section"><a href="callable_traits/parameter_list_features.html#callable_traits.parameter_list_features.ref_clear_args">clear_args</a></span></dt>
<dt><span class="section"><a href="callable_traits/parameter_list_features.html#callable_traits.parameter_list_features.ref_remove_args">remove_args</a></span></dt>
<dt><span class="section"><a href="callable_traits/parameter_list_features.html#callable_traits.parameter_list_features.ref_replace_args">replace_args</a></span></dt>
<dt><span class="section"><a href="callable_traits/parameter_list_features.html#callable_traits.parameter_list_features.ref_insert_args">insert_args</a></span></dt>
<dt><span class="section"><a href="callable_traits/parameter_list_features.html#callable_traits.parameter_list_features.ref_pop_back_args">pop_back_args</a></span></dt>
<dt><span class="section"><a href="callable_traits/parameter_list_features.html#callable_traits.parameter_list_features.ref_pop_front_args">pop_front_args</a></span></dt>
<dt><span class="section"><a href="callable_traits/parameter_list_features.html#callable_traits.parameter_list_features.ref_push_back_args">push_back_args</a></span></dt>
<dt><span class="section"><a href="callable_traits/parameter_list_features.html#callable_traits.parameter_list_features.ref_push_front_args">push_front_args</a></span></dt>
<dt><span class="section"><a href="callable_traits/parameter_list_features.html#callable_traits.parameter_list_features.ref_expand_args">expand_args</a></span></dt>
<dt><span class="section"><a href="callable_traits/parameter_list_features.html#callable_traits.parameter_list_features.ref_expand_args_left">expand_args_left</a></span></dt>
<dt><span class="section"><a href="callable_traits/parameter_list_features.html#callable_traits.parameter_list_features.ref_expand_args_right">expand_args_right</a></span></dt>
<dt><span class="section"><a href="callable_traits/parameter_list_features.html#callable_traits.parameter_list_features.ref_add_varargs">add_varargs</a></span></dt>
<dt><span class="section"><a href="callable_traits/parameter_list_features.html#callable_traits.parameter_list_features.ref_remove_varargs">remove_varargs</a></span></dt>
<dt><span class="section"><a href="callable_traits/parameter_list_features.html#callable_traits.parameter_list_features.ref_has_varargs">has_varargs</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="callable_traits/return_type_features.html">Return Type Features</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="callable_traits/return_type_features.html#callable_traits.return_type_features.ref_return_type">return_type</a></span></dt>
<dt><span class="section"><a href="callable_traits/return_type_features.html#callable_traits.return_type_features.ref_apply_return">apply_return</a></span></dt>
<dt><span class="section"><a href="callable_traits/return_type_features.html#callable_traits.return_type_features.ref_has_void_return">has_void_return</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="callable_traits/member_pointer_features.html">Member Pointer
Features</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="callable_traits/member_pointer_features.html#callable_traits.member_pointer_features.ref_apply_member_pointer">apply_member_pointer</a></span></dt>
<dt><span class="section"><a href="callable_traits/member_pointer_features.html#callable_traits.member_pointer_features.ref_parent_class_of">parent_class_of</a></span></dt>
<dt><span class="section"><a href="callable_traits/member_pointer_features.html#callable_traits.member_pointer_features.ref_qualified_parent_class_of">qualified_parent_class_of</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="callable_traits/cpp_17_features.html">C++17 Features</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="callable_traits/cpp_17_features.html#callable_traits.cpp_17_features.ref_add_transaction_safe">add_transaction_safe</a></span></dt>
<dt><span class="section"><a href="callable_traits/cpp_17_features.html#callable_traits.cpp_17_features.ref_remove_transaction_safe">remove_transaction_safe</a></span></dt>
<dt><span class="section"><a href="callable_traits/cpp_17_features.html#callable_traits.cpp_17_features.ref_is_transaction_safe">is_transaction_safe</a></span></dt>
<dt><span class="section"><a href="callable_traits/cpp_17_features.html#callable_traits.cpp_17_features.ref_add_noexcept">add_noexcept</a></span></dt>
<dt><span class="section"><a href="callable_traits/cpp_17_features.html#callable_traits.cpp_17_features.ref_remove_noexcept">remove_noexcept</a></span></dt>
<dt><span class="section"><a href="callable_traits/cpp_17_features.html#callable_traits.cpp_17_features.ref_is_noexcept">is_noexcept</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="callable_traits/building.html">Building the test suite</a></span></dt>
<dt><span class="section"><a href="callable_traits/contact.html">Contact</a></span></dt>
</dl>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="callable_traits.introduction"></a><a class="link" href="index.html#callable_traits.introduction" title="Overview">Overview</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="index.html#callable_traits.introduction.motivation">Motivation</a></span></dt>
<dt><span class="section"><a href="index.html#callable_traits.introduction.boost_function_types">Regarding
<code class="literal">Boost.FunctionTypes</code></a></span></dt>
<dt><span class="section"><a href="index.html#callable_traits.introduction.compatibility">Compatibility</a></span></dt>
</dl></div>
<p>
<code class="literal">CallableTraits</code> is a C++11/14/17 library for the inspection,
synthesis, and decomposition of callable types. <code class="literal">CallableTraits</code>
aims to be the "complete type manipulation facility for function types"
mentioned in the final paragraph of C++17 proposal <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2015/p0172r0.html" target="_top">p0172</a>,
and removes the need for template specializations for different function signatures.
</p>
<p>
<code class="literal">CallableTraits</code> is...
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
header-only
</li>
<li class="listitem">
dependency-free, only using the C++11 stdlib
</li>
<li class="listitem">
cross-platform, compatible with all major C++ compilers
</li>
<li class="listitem">
thoroughly tested
</li>
<li class="listitem">
currently hosted at <a href="https://github.com/badair/callable_traits" target="_top">GitHub</a>
</li>
<li class="listitem">
not a Boost library
</li>
</ul></div>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">type_traits</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">tuple</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">callable_traits</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">namespace</span> <span class="identifier">ct</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">callable_traits</span><span class="special">;</span>
<span class="comment">// This function template helps keep our example code neat</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">B</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">assert_same</span><span class="special">(){</span> <span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span> <span class="identifier">B</span><span class="special">&gt;::</span><span class="identifier">value</span><span class="special">,</span> <span class="string">""</span><span class="special">);</span> <span class="special">}</span>
<span class="comment">// foo is a function object</span>
<span class="keyword">struct</span> <span class="identifier">foo</span> <span class="special">{</span>
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">,</span> <span class="keyword">float</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{}</span>
<span class="special">};</span>
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
<span class="comment">// Use args_t to retrieve a parameter list as a std::tuple:</span>
<span class="identifier">assert_same</span><span class="special">&lt;</span>
<span class="identifier">ct</span><span class="special">::</span><span class="identifier">args_t</span><span class="special">&lt;</span><span class="identifier">foo</span><span class="special">&gt;,</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">,</span> <span class="keyword">float</span><span class="special">&gt;</span>
<span class="special">&gt;();</span>
<span class="comment">// arg_at_t gives us indexed access to a parameter list</span>
<span class="identifier">assert_same</span><span class="special">&lt;</span>
<span class="identifier">ct</span><span class="special">::</span><span class="identifier">arg_at_t</span><span class="special">&lt;</span><span class="number">1</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">&gt;,</span>
<span class="keyword">char</span>
<span class="special">&gt;();</span>
<span class="comment">// has_void_return lets us perform a quick check for a void return type</span>
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">has_void_return_v</span><span class="special">&lt;</span><span class="identifier">foo</span><span class="special">&gt;,</span> <span class="string">""</span><span class="special">);</span>
<span class="comment">// Detect C-style variadics (ellipses) in a signature (e.g. printf)</span>
<span class="keyword">static_assert</span><span class="special">(!</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">has_varargs_v</span><span class="special">&lt;</span><span class="identifier">foo</span><span class="special">&gt;,</span> <span class="string">""</span><span class="special">);</span>
<span class="comment">// pmf is a pointer-to-member function: void (foo::*)(int, char, float) const</span>
<span class="keyword">using</span> <span class="identifier">pmf</span> <span class="special">=</span> <span class="keyword">decltype</span><span class="special">(&amp;</span><span class="identifier">foo</span><span class="special">::</span><span class="keyword">operator</span><span class="special">());</span>
<span class="comment">// remove_member_const_t lets you remove the const member qualifier</span>
<span class="identifier">assert_same</span><span class="special">&lt;</span>
<span class="identifier">ct</span><span class="special">::</span><span class="identifier">remove_member_const_t</span><span class="special">&lt;</span><span class="identifier">pmf</span><span class="special">&gt;,</span>
<span class="keyword">void</span> <span class="special">(</span><span class="identifier">foo</span><span class="special">::*)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">,</span> <span class="keyword">float</span><span class="special">)</span> <span class="comment">/*no const!*/</span>
<span class="special">&gt;();</span>
<span class="comment">// Conversely, add_member_const_t adds a const member qualifier</span>
<span class="identifier">assert_same</span><span class="special">&lt;</span>
<span class="identifier">pmf</span><span class="special">,</span>
<span class="identifier">ct</span><span class="special">::</span><span class="identifier">add_member_const_t</span><span class="special">&lt;</span><span class="keyword">void</span> <span class="special">(</span><span class="identifier">foo</span><span class="special">::*)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">,</span> <span class="keyword">float</span><span class="special">)&gt;</span>
<span class="special">&gt;();</span>
<span class="comment">// is_const_member_v checks for the presence of member const</span>
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">is_const_member_v</span><span class="special">&lt;</span><span class="identifier">pmf</span><span class="special">&gt;,</span> <span class="string">""</span><span class="special">);</span>
<span class="comment">// pop_front_args_t removes the first parameter from signature:</span>
<span class="identifier">assert_same</span><span class="special">&lt;</span>
<span class="identifier">ct</span><span class="special">::</span><span class="identifier">pop_front_args_t</span><span class="special">&lt;</span><span class="identifier">pmf</span><span class="special">&gt;,</span>
<span class="keyword">void</span> <span class="special">(</span><span class="identifier">foo</span><span class="special">::*)(/*</span><span class="keyword">int</span> <span class="identifier">is</span> <span class="identifier">gone</span><span class="special">!*/</span> <span class="keyword">char</span><span class="special">,</span> <span class="keyword">float</span><span class="special">)</span> <span class="keyword">const</span>
<span class="special">&gt;();</span>
<span class="comment">// clear_args_t removes all parameter types:</span>
<span class="identifier">assert_same</span><span class="special">&lt;</span>
<span class="identifier">ct</span><span class="special">::</span><span class="identifier">clear_args_t</span><span class="special">&lt;</span><span class="identifier">pmf</span><span class="special">&gt;,</span>
<span class="keyword">void</span> <span class="special">(</span><span class="identifier">foo</span><span class="special">::*)(/*</span> <span class="identifier">nothing</span> <span class="identifier">to</span> <span class="identifier">see</span> <span class="identifier">here</span><span class="special">!</span> <span class="special">*/)</span> <span class="keyword">const</span>
<span class="special">&gt;();</span>
<span class="special">}</span>
<span class="comment">// This program is just a glimpse at CallableTraits' features. There</span>
<span class="comment">// are many more traits and metafunctions which are not shown here. Every</span>
<span class="comment">// feature is demonstrated and specified in the reference documentation.</span>
</pre>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="callable_traits.introduction.motivation"></a><a class="link" href="index.html#callable_traits.introduction.motivation" title="Motivation">Motivation</a>
</h3></div></div></div>
<div class="blockquote"><blockquote class="blockquote">
<p>
<span class="bold"><strong><span class="emphasis"><em><span class="quote">&#8220;<span class="quote">Don't try to write helper code to
detect PMFs/PMDs and dispatch on them -- it is an <span class="underline">absolute
nightmare</span>. PMF types are the worst types by far in the core
language.</span>&#8221;</span></em></span></strong></span>
</p>
<p>
-- Stephan T. Lavavej, CppCon 2015, <a href="https://www.youtube.com/watch?v=zt7ThwVfap0&amp;t=11m40s" target="_top">"functional:
What's New, And Proper Usage"</a>
</p>
</blockquote></div>
<p>
Consider for a moment the code below, which defines all 24 template specializations
necessary to account for all the function types in C++11 and C++14:
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special">;</span>
<span class="comment">//function type without varargs</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Return</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special">&lt;</span><span class="identifier">Return</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...)&gt;</span> <span class="special">{};</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Return</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special">&lt;</span><span class="identifier">Return</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...)</span> <span class="special">&amp;&gt;</span> <span class="special">{};</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Return</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special">&lt;</span><span class="identifier">Return</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...)</span> <span class="special">&amp;&amp;&gt;</span> <span class="special">{};</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Return</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special">&lt;</span><span class="identifier">Return</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...)</span> <span class="keyword">const</span><span class="special">&gt;</span> <span class="special">{};</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Return</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special">&lt;</span><span class="identifier">Return</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...)</span> <span class="keyword">const</span> <span class="special">&amp;&gt;</span> <span class="special">{};</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Return</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special">&lt;</span><span class="identifier">Return</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...)</span> <span class="keyword">const</span> <span class="special">&amp;&amp;&gt;</span> <span class="special">{};</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Return</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special">&lt;</span><span class="identifier">Return</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...)</span> <span class="keyword">volatile</span><span class="special">&gt;</span> <span class="special">{};</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Return</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special">&lt;</span><span class="identifier">Return</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...)</span> <span class="keyword">volatile</span> <span class="special">&amp;&gt;</span> <span class="special">{};</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Return</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special">&lt;</span><span class="identifier">Return</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...)</span> <span class="keyword">volatile</span> <span class="special">&amp;&amp;&gt;</span> <span class="special">{};</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Return</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special">&lt;</span><span class="identifier">Return</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...)</span> <span class="keyword">const</span> <span class="keyword">volatile</span><span class="special">&gt;</span> <span class="special">{};</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Return</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special">&lt;</span><span class="identifier">Return</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...)</span> <span class="keyword">const</span> <span class="keyword">volatile</span> <span class="special">&amp;&gt;</span> <span class="special">{};</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Return</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special">&lt;</span><span class="identifier">Return</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...)</span> <span class="keyword">const</span> <span class="keyword">volatile</span> <span class="special">&amp;&amp;&gt;</span> <span class="special">{};</span>
<span class="comment">//function type with varargs</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Return</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special">&lt;</span><span class="identifier">Return</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...,</span> <span class="special">...)&gt;</span> <span class="special">{};</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Return</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special">&lt;</span><span class="identifier">Return</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...,</span> <span class="special">...)</span> <span class="special">&amp;&gt;</span> <span class="special">{};</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Return</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special">&lt;</span><span class="identifier">Return</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...,</span> <span class="special">...)</span> <span class="special">&amp;&amp;&gt;</span> <span class="special">{};</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Return</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special">&lt;</span><span class="identifier">Return</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...,</span> <span class="special">...)</span> <span class="keyword">const</span><span class="special">&gt;</span> <span class="special">{};</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Return</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special">&lt;</span><span class="identifier">Return</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...,</span> <span class="special">...)</span> <span class="keyword">const</span> <span class="special">&amp;&gt;</span> <span class="special">{};</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Return</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special">&lt;</span><span class="identifier">Return</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...,</span> <span class="special">...)</span> <span class="keyword">const</span> <span class="special">&amp;&amp;&gt;</span> <span class="special">{};</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Return</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special">&lt;</span><span class="identifier">Return</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...,</span> <span class="special">...)</span> <span class="keyword">volatile</span><span class="special">&gt;</span> <span class="special">{};</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Return</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special">&lt;</span><span class="identifier">Return</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...,</span> <span class="special">...)</span> <span class="keyword">volatile</span> <span class="special">&amp;&gt;</span> <span class="special">{};</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Return</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special">&lt;</span><span class="identifier">Return</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...,</span> <span class="special">...)</span> <span class="keyword">volatile</span> <span class="special">&amp;&amp;&gt;</span> <span class="special">{};</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Return</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special">&lt;</span><span class="identifier">Return</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...,</span> <span class="special">...)</span> <span class="keyword">const</span> <span class="keyword">volatile</span><span class="special">&gt;</span> <span class="special">{};</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Return</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special">&lt;</span><span class="identifier">Return</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...,</span> <span class="special">...)</span> <span class="keyword">const</span> <span class="keyword">volatile</span> <span class="special">&amp;&gt;</span> <span class="special">{};</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Return</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special">&lt;</span><span class="identifier">Return</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...,</span> <span class="special">...)</span> <span class="keyword">const</span> <span class="keyword">volatile</span> <span class="special">&amp;&amp;&gt;</span> <span class="special">{};</span>
</pre>
<p>
Things get even more complicated with member function pointers, function
pointers, function references, function objects, and C++17 <code class="computeroutput"><span class="identifier">transaction_safe</span></code>/<code class="computeroutput"><span class="keyword">noexcept</span></code>.
</p>
<p>
Granted, use cases for such obscure specializations are vitually nonexistent
in run-of-the-mill application codebases. Even in library code, these are
exceedingly rare. However, there are a handful of very specific metaprogramming
scenarios that can only be solved with this kind of template "spam".
Writing and testing these templates is tedious and time consuming, and often
requires lots of code duplication.
</p>
<p>
<code class="literal">CallableTraits</code> offers a final and decisive library-level
solution to this problem, and removes the need for these specializations
entirely (except for platform-specific calling conventions).
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="callable_traits.introduction.boost_function_types"></a><a class="link" href="index.html#callable_traits.introduction.boost_function_types" title="Regarding Boost.FunctionTypes">Regarding
<code class="literal">Boost.FunctionTypes</code></a>
</h3></div></div></div>
<p>
The use cases for <code class="literal">CallableTraits</code> overlaop significantly
with those of <a href="http://www.boost.org/doc/libs/1_61_0/libs/function_types/doc/html/index.html" target="_top"><code class="literal">Boost.FunctionTypes</code></a>.
Here are some reasons why you might prefer <code class="literal">CallableTraits</code>
over the latter:
</p>
<div class="orderedlist"><ol class="orderedlist" type="1">
<li class="listitem">
<code class="literal">Boost.FunctionTypes</code> is tightly coupled to <a href="http://www.boost.org/doc/libs/1_60_0/libs/mpl/doc/index.html" target="_top"><code class="literal">Boost.MPL</code></a>
sequences, while <code class="literal">CallableTraits</code> generally takes a
lower-level approach. No knowledge of MPL terminology is needed to use
<code class="literal">CallableTraits</code>.
</li>
<li class="listitem">
Other types in C++ receive fine-grained, low-level attention in <code class="literal">Boost.TypeTraits</code>
and <code class="literal">&lt;type_traits&gt;</code>. <code class="literal">CallableTraits</code>
gives callable types similar attention, without additional metaprogramming
dependencies.
</li>
<li class="listitem">
<code class="literal">CallableTraits</code> aims to eliminate function type template
specializations. <code class="literal">Boost.FunctionTypes</code> does not.
</li>
<li class="listitem">
<code class="literal">CallableTraits</code> targets C++11/14/17 features. <code class="literal">Boost.FunctionTypes</code>
does not.
</li>
<li class="listitem">
The <code class="literal">Boost.FunctionTypes</code> interface relies heavily on
tag types. <code class="literal">CallableTraits</code> does not.
</li>
</ol></div>
<p>
<code class="literal">Boost.FunctionTypes</code> is a good tool for projects already
dependent on the MPL, which must also support very old compilers. However,
the <code class="literal">Boost.FunctionTypes</code> interface is unpleasant to use.
It relies heavily on both the MPL and tag types, for problems that are more
simply solved with neither. Using <code class="literal">Boost.FunctionTypes</code>
requires an understanding of the library's "big picture."
</p>
<p>
<code class="literal">CallableTraits</code> reimplements much of the functionality
found in <code class="literal">Boost.FunctionTypes</code>, but offers a much more accessible
<code class="computeroutput"><span class="identifier">type_traits</span></code>-style interface.
There is nothing inherently wrong with <code class="literal">Boost.FunctionTypes</code>,
but an MPL sequence-based solution with no C++11/14/17 support should not
be the only library option for inspecting and manipulating callable types.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="callable_traits.introduction.compatibility"></a><a class="link" href="index.html#callable_traits.introduction.compatibility" title="Compatibility">Compatibility</a>
</h3></div></div></div>
<p>
<code class="literal">CallableTraits</code> is tested on GCC 4.7.4 and later, Clang
3.5 and later, XCode 6.4 and later, and Visual Studio 2015. Continuous integration
is managed on <a href="https://ci.appveyor.com/project/badair/callable-traits" target="_top">Appveyor</a>
for Visual Studio, and on <a href="https://travis-ci.org/badair/callable_traits/builds" target="_top">Travis</a>
for everything else.
</p>
<p>
The reference documentation for each feature includes compatibility notes
that may mention behavior differences between compiler versions. The compatibility
claims in this documentation assume compilation with the highest available
C++ version flag, such as <code class="computeroutput"><span class="special">-</span><span class="identifier">std</span><span class="special">=</span><span class="identifier">C</span><span class="special">++</span><span class="number">0</span><span class="identifier">x</span></code>
for older versions of GCC, or <code class="computeroutput"><span class="identifier">std</span><span class="special">=</span><span class="identifier">C</span><span class="special">++</span><span class="number">1</span><span class="identifier">z</span></code> for GCC
6.
</p>
</div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer"></div></td>
</tr></table>
<hr>
<div class="spirit-nav"><a accesskey="n" href="callable_traits/faq.html"><img src="../src/images/next.png" alt="Next"></a></div>
</body>
</html>