Files
callable_traits/doc/html/index.html
2016-04-14 04:25:51 -05:00

596 lines
90 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/function_sugar_example.html" title="Example: std::function sugar">
</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/function_sugar_example.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">Introduction</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="index.html#callable_traits.introduction.prereqs">Prerequisite Topics</a></span></dt>
<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.quick_example">Quick Example</a></span></dt>
<dt><span class="section"><a href="index.html#callable_traits.introduction.reasons">What makes <code class="literal">CallableTraits</code>
unique?</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="callable_traits/function_sugar_example.html">Example: <code class="literal">std::function</code>
sugar</a></span></dt>
<dt><span class="section"><a href="callable_traits/compatibility.html">Compatibility</a></span></dt>
<dd><dl><dt><span class="section"><a href="callable_traits/compatibility.html#callable_traits.compatibility.msvc_issues">MSVC Issues</a></span></dt></dl></dd>
<dt><span class="section"><a href="callable_traits/concepts.html">Concepts</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="callable_traits/concepts.html#callable_traits.concepts.ref_fn_ptr"><span class="green">FunctionPtr</span></a></span></dt>
<dt><span class="section"><a href="callable_traits/concepts.html#callable_traits.concepts.ref_fn_ref"><span class="green">FunctionReference</span></a></span></dt>
<dt><span class="section"><a href="callable_traits/concepts.html#callable_traits.concepts.ref_simple_fn"><span class="green">UnqualifiedFunction</span></a></span></dt>
<dt><span class="section"><a href="callable_traits/concepts.html#callable_traits.concepts.ref_abominable"><span class="green">AbominableFunction</span></a></span></dt>
<dt><span class="section"><a href="callable_traits/concepts.html#callable_traits.concepts.ref_fn"><span class="green">Function</span></a></span></dt>
<dt><span class="section"><a href="callable_traits/concepts.html#callable_traits.concepts.ref_pmf"><span class="green">MemberFunctionPtr</span></a></span></dt>
<dt><span class="section"><a href="callable_traits/concepts.html#callable_traits.concepts.ref_pmd"><span class="green">MemberDataPtr</span></a></span></dt>
<dt><span class="section"><a href="callable_traits/concepts.html#callable_traits.concepts.ref_member_ptr"><span class="green">MemberPtr</span></a></span></dt>
<dt><span class="section"><a href="callable_traits/concepts.html#callable_traits.concepts.ref_simple_fn_obj"><span class="green">SimpleFunctionObject</span></a></span></dt>
<dt><span class="section"><a href="callable_traits/concepts.html#callable_traits.concepts.ref_overloaded_fn_obj"><span class="green">OverloadedFunctionObject</span></a></span></dt>
<dt><span class="section"><a href="callable_traits/concepts.html#callable_traits.concepts.ref_fn_obj"><span class="green">FunctionObject</span></a></span></dt>
<dt><span class="section"><a href="callable_traits/concepts.html#callable_traits.concepts.ref_signature"><span class="green">Signature</span></a></span></dt>
<dt><span class="section"><a href="callable_traits/concepts.html#callable_traits.concepts.ref_callable"><span class="green">Callable</span></a></span></dt>
<dt><span class="section"><a href="callable_traits/concepts.html#callable_traits.concepts.ref_simple_callable"><span class="green">SimpleCallable</span></a></span></dt>
<dt><span class="section"><a href="callable_traits/concepts.html#callable_traits.concepts.ref_simple_invokable"><span class="green">SimpleInvokable</span></a></span></dt>
<dt><span class="section"><a href="callable_traits/concepts.html#callable_traits.concepts.ref_invokable"><span class="green">Invokable</span></a></span></dt>
<dt><span class="section"><a href="callable_traits/concepts.html#callable_traits.concepts.ref_bind_expression"><span class="green">BindExpression</span></a></span></dt>
<dt><span class="section"><a href="callable_traits/concepts.html#callable_traits.concepts.ref_constexpr_constructible"><span class="green">ConstexprDefaultConstructible</span></a></span></dt>
<dt><span class="section"><a href="callable_traits/concepts.html#callable_traits.concepts.ref_cc_tag"><span class="green">CallingConventionTag</span></a></span></dt>
</dl></dd>
<dt><span class="section"><a href="callable_traits/headers.html">Headers</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_add_calling_convention.html">add_calling_convention</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_add_member_const.html">add_member_const</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_add_member_cv.html">add_member_cv</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_add_member_lvalue_reference.html">add_member_lvalue_reference</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_add_member_rvalue_reference.html">add_member_rvalue_reference</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_add_varargs.html">add_varargs</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_add_member_volatile.html">add_member_volatile</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_apply_member_pointer.html">apply_member_pointer</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_apply_return.html">apply_return</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_arg_at.html">arg_at</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_args.html">args</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_arity.html">arity</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_bind.html">bind</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_can_invoke.html">can_invoke</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_can_invoke_constexpr.html">can_invoke_constexpr</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_function_type.html">function_type</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_has_calling_convention.html">has_calling_convention</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_has_varargs.html">has_varargs</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_has_void_return.html">has_void_return</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_is_const_member.html">is_const_member</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_is_constexpr.html">is_constexpr</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_is_lvalue_reference_member.html">is_lvalue_reference_member</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_is_reference_member.html">is_reference_member</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_is_rvalue_reference_member.html">is_rvalue_reference_member</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_has_member_qualifiers.html">has_member_qualifiers</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_is_volatile_member.html">is_volatile_member</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_max_arity.html">max_arity</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_min_arity.html">min_arity</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_qualified_function_type.html">qualified_function_type</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_remove_calling_convention.html">remove_calling_convention</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_remove_member_const.html">remove_member_const</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_remove_member_cv.html">remove_member_cv</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_remove_member_pointer.html">remove_member_pointer</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_remove_member_reference.html">remove_member_reference</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_remove_varargs.html">remove_varargs</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_remove_member_volatile.html">remove_member_volatile</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_result_of.html">result_of</a></span></dt>
<dt><span class="section"><a href="callable_traits/acknowledgements.html">Acknowledgements</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="Introduction">Introduction</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="index.html#callable_traits.introduction.prereqs">Prerequisite Topics</a></span></dt>
<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.quick_example">Quick Example</a></span></dt>
<dt><span class="section"><a href="index.html#callable_traits.introduction.reasons">What makes <code class="literal">CallableTraits</code>
unique?</a></span></dt>
</dl></div>
<p>
<code class="literal">CallableTraits</code> is a cross-platform C++14 library for the
inspection, decomposition, and synthesis of C++ callable types. <code class="literal">CallableTraits</code>
is header-only, and does not depend on any non-standard headers. <code class="literal">CallableTraits</code>
is currently hosted at <a href="https://github.com/badair/callable_traits" target="_top">GitHub</a>.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
<code class="literal">CallableTraits</code> is not a Boost library.
</p></td></tr>
</table></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="callable_traits.introduction.prereqs"></a><a class="link" href="index.html#callable_traits.introduction.prereqs" title="Prerequisite Topics">Prerequisite Topics</a>
</h3></div></div></div>
<p>
This documentation will be most beneficial to readers who posess a basic
understanding of the following C++ features:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<a href="http://en.cppreference.com/w/cpp/language/partial_specialization" target="_top">template
specializations</a>
</li>
<li class="listitem">
<a href="http://en.cppreference.com/w/cpp/language/sfinae" target="_top">SFINAE</a>
</li>
<li class="listitem">
<a href="http://en.cppreference.com/w/cpp/utility/functional/invoke" target="_top"><code class="literal"><span class="emphasis"><em>INVOKE</em></span></code></a>
rules
</li>
<li class="listitem">
function types
</li>
<li class="listitem">
<a href="http://en.cppreference.com/w/cpp/language/pointer#Pointers_to_functions" target="_top">function
pointers</a>
</li>
<li class="listitem">
<a href="http://stackoverflow.com/questions/480248/function-references" target="_top">function
references</a>
</li>
<li class="listitem">
<a href="http://en.cppreference.com/w/cpp/language/pointer#Pointers_to_member_functions" target="_top">pointers
to member functions</a>
</li>
<li class="listitem">
<a href="http://en.cppreference.com/w/cpp/language/pointer#Pointers_to_data_members" target="_top">pointers
to data members</a>
</li>
<li class="listitem">
<a href="http://en.cppreference.com/w/cpp/language/operators#Function_call_operator" target="_top">the
function call operator, <code class="literal">operator()</code></a>
</li>
<li class="listitem">
<a href="https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers" target="_top">universal
references</a> and <a href="http://stackoverflow.com/questions/13725747/concise-explanation-of-reference-collapsing-rules-requested-1-a-a-2" target="_top">reference
collapsing rules</a>
</li>
<li class="listitem">
<a href="http://en.cppreference.com/w/cpp/language/member_functions#const-.2C_volatile-.2C_and_ref-qualified_member_functions" target="_top">cv-qualified
and ref-qualified member functions</a>
</li>
<li class="listitem">
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0172r0.html" target="_top">"abominable"
function types</a>
</li>
<li class="listitem">
<a href="http://en.cppreference.com/w/cpp/language/overloaded_address" target="_top">taking
the address of overloaded functions</a>
</li>
<li class="listitem">
<a href="http://en.cppreference.com/w/c/language/variadic" target="_top">C-style
variadics</a>, a.k.a. varargs
</li>
<li class="listitem">
<a href="https://en.wikipedia.org/wiki/X86_calling_conventions" target="_top">calling
conventions</a>
</li>
<li class="listitem">
<a href="http://en.cppreference.com/w/cpp/utility/functional/bind" target="_top">std::bind
expressions</a> with <a href="http://en.cppreference.com/w/cpp/utility/functional/placeholders" target="_top">std::placeholders</a>
</li>
</ul></div>
</div>
<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>
<p>
Consider for a moment the class template below, which defines all <span class="red"><span class="bold"><strong>48</strong></span></span> template specializations
necessary to account for all valid function types and member function pointer
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>
<span class="comment">//member function pointer 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="identifier">T</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">T</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="identifier">T</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">T</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="identifier">T</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">T</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="identifier">T</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">T</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="identifier">T</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">T</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="identifier">T</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">T</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="identifier">T</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">T</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="identifier">T</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">T</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="identifier">T</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">T</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="identifier">T</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">T</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="identifier">T</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">T</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="identifier">T</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">T</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">//member function pointer 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="identifier">T</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">T</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="identifier">T</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">T</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="identifier">T</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">T</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="identifier">T</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">T</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="identifier">T</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">T</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="identifier">T</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">T</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="identifier">T</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">T</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="identifier">T</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">T</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="identifier">T</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">T</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="identifier">T</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">T</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="identifier">T</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">T</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="identifier">T</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">T</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>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
The upcoming ISO standard for C++17 includes a <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0012r1.html" target="_top">change
to the core language</a> which adds the <code class="literal">noexcept</code>
qualifier to the type system. If the author's understanding is correct,
this would increase the the count of necessary template specializations
to <span class="red"><span class="bold"><strong>96</strong></span></span> (<a class="link" href="callable_traits/contact.html" title="Contact">feedback</a>?). Currently, C++17
<code class="computeroutput"><span class="keyword">noexcept</span></code> qualifiers are not
handled in <code class="literal">CallableTraits</code>, because compiler vendors
have not implemented support for this feature (to best of the author's
knowledge). However, features to account for and manipulate <code class="computeroutput"><span class="keyword">noexcept</span></code> qualifiers are planned in <code class="literal">CallableTraits</code>,
as soon as feature is implemented by a compiler vendor. Of course, the
<code class="literal">CallableTraits</code> feature additions will be non-breaking
for currently supported compiler versions.
</p></td></tr>
</table></div>
<p>
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 such template "spam". While these use cases
are indeed rare, the writing and testing of these templates is incredibly
tedious and time consuming. On this premise, <code class="literal">CallableTraits</code>
offers a final and decisive library-level solution, so that authors of generic
code will <span class="bold"><strong>never again</strong></span> need to write these
specializations, for <span class="emphasis"><em>any</em></span> reason.
</p>
<p>
Template specializations like those in the code snippet above <span class="emphasis"><em>still</em></span>
do not account for function pointers, function references, function objects/lambdas,
or calling conventions. <code class="literal">CallableTraits</code> goes the extra
mile by accounting for all of them.
</p>
<div class="warning"><table border="0" summary="Warning">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../src/images/warning.png"></td>
<th align="left">Warning</th>
</tr>
<tr><td align="left" valign="top">
<p>
Features for the manipulation and inspection of calling conventions are
optional, which must be enabled with macro definitions. The features regarding
them are currently classified as <span class="emphasis"><em>experimental</em></span>, and
are subject to breaking changes in future versions of <code class="literal">CallableTraits</code>.
</p>
<p>
The rationale for classifying the calling convention features as "experimental"
is three-fold:
</p>
<div class="orderedlist"><ol class="orderedlist" type="1">
<li class="listitem">
Calling conventions are, by definition, highly platform-specific.
</li>
<li class="listitem">
The inclusion of a single calling convention effectively doubles the
test surface of <code class="literal">CallableTraits</code> <span class="emphasis"><em>on every
platform</em></span>.
</li>
<li class="listitem">
The author's current knowledge of calling conventions is admittedly
limited.
</li>
</ol></div>
<p>
It is the author's hope that future versions of <code class="literal">CallableTraits</code>
will offer a stable, thoroughly-tested, and well-documented implementation
of these features. If you have experience in this domain, your <a class="link" href="callable_traits/contact.html" title="Contact">feedback</a>
is <span class="emphasis"><em>highly</em></span> appreciated.
</p>
</td></tr>
</table></div>
<p>
The use cases for <code class="literal">CallableTraits</code> are closely related to
those of <a href="http://www.boost.org/doc/libs/1_60_0/libs/type_traits/doc/html/boost_typetraits/reference/function_traits.html" target="_top">function_traits</a>
and <a href="http://www.boost.org/doc/libs/1_60_0/libs/function_types/doc/html/index.html" target="_top">Boost.FunctionTypes</a>.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="callable_traits.introduction.quick_example"></a><a class="link" href="index.html#callable_traits.introduction.quick_example" title="Quick Example">Quick Example</a>
</h3></div></div></div>
<p>
This short program showcases some, but not all, of the features available
in <code class="literal">CallableTraits</code>.
</p>
<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">functional</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">callable_traits</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">callable_traits</span><span class="special">;</span>
<span class="comment">// foo is an example of 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">int</span><span class="special">&amp;&amp;,</span> <span class="keyword">const</span> <span class="keyword">int</span><span class="special">&amp;,</span> <span class="keyword">void</span><span class="special">*</span> <span class="special">=</span> <span class="keyword">nullptr</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">// indexed argument types</span>
<span class="keyword">using</span> <span class="identifier">second_arg</span> <span class="special">=</span> <span class="identifier">ct</span><span class="special">::</span><span class="identifier">arg_at</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">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">second_arg</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&amp;&amp;&gt;::</span><span class="identifier">value</span><span class="special">,</span> <span class="string">""</span><span class="special">);</span>
<span class="comment">// arg types are packaged into std::tuple, which serves as the default</span>
<span class="comment">// type list in <code class="literal">CallableTraits</code> (runtime capabilities are not used).</span>
<span class="keyword">using</span> <span class="identifier">args</span> <span class="special">=</span> <span class="identifier">ct</span><span class="special">::</span><span class="identifier">args</span><span class="special">&lt;</span><span class="identifier">foo</span><span class="special">&gt;;</span>
<span class="keyword">using</span> <span class="identifier">expected_args</span> <span class="special">=</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">int</span><span class="special">&amp;&amp;,</span> <span class="keyword">const</span> <span class="keyword">int</span><span class="special">&amp;,</span> <span class="keyword">void</span><span class="special">*&gt;;</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">args</span><span class="special">,</span> <span class="identifier">expected_args</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="comment">// <code class="literal">callable_traits::</code>function_type "decays" a callable type to a plain</span>
<span class="comment">// function type, which is structured in terms of INVOKE.</span>
<span class="keyword">using</span> <span class="identifier">function_type</span> <span class="special">=</span> <span class="identifier">ct</span><span class="special">::</span><span class="identifier">function_type</span><span class="special">&lt;</span><span class="identifier">foo</span><span class="special">&gt;;</span>
<span class="keyword">using</span> <span class="identifier">expected_function_type</span> <span class="special">=</span> <span class="keyword">void</span><span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&amp;&amp;,</span> <span class="keyword">const</span> <span class="keyword">int</span><span class="special">&amp;,</span> <span class="keyword">void</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">function_type</span><span class="special">,</span> <span class="identifier">expected_function_type</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="comment">// By design, the <code class="literal">CallableTraits</code> interface uses constexpr</span>
<span class="comment">// std::integral_constant functions (whenever sensible).</span>
<span class="comment">// By also defining the appropriate overloads, this gives</span>
<span class="comment">// users the option of using either type arguments or a value</span>
<span class="comment">// arguments, which often eliminates the need for decltype:</span>
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">arity</span><span class="special">&lt;</span><span class="identifier">foo</span><span class="special">&gt;()</span> <span class="special">==</span> <span class="number">4</span><span class="special">,</span> <span class="string">""</span><span class="special">);</span>
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">arity</span><span class="special">(</span><span class="identifier">foo</span><span class="special">{})</span> <span class="special">==</span> <span class="number">4</span><span class="special">,</span> <span class="string">""</span><span class="special">);</span>
<span class="comment">// Attentive readers might notice that the type of the foo{}</span>
<span class="comment">// expression above is foo&amp;&amp;, rather than foo. Indeed,</span>
<span class="comment">// <code class="literal">CallableTraits</code> is designed to also allow both ref-qualified</span>
<span class="comment">// and cv-qualified arguments across the board:</span>
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">arity</span><span class="special">&lt;</span><span class="identifier">foo</span><span class="special">&amp;&amp;&gt;()</span> <span class="special">==</span> <span class="number">4</span><span class="special">,</span> <span class="string">""</span><span class="special">);</span>
<span class="comment">// Now, if foo had an operator() overload with a &amp;&amp; qualifier, taking</span>
<span class="comment">// a different number of arguments, the above static assert would fail.</span>
<span class="comment">// For consistency, we'll avoid the value-style overloads</span>
<span class="comment">// for the remainder of this example (whenever possible).</span>
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">max_arity</span><span class="special">&lt;</span><span class="identifier">foo</span><span class="special">&gt;()</span> <span class="special">==</span> <span class="number">4</span><span class="special">,</span> <span class="string">""</span><span class="special">);</span>
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">min_arity</span><span class="special">&lt;</span><span class="identifier">foo</span><span class="special">&gt;()</span> <span class="special">==</span> <span class="number">3</span><span class="special">,</span> <span class="string">""</span><span class="special">);</span>
<span class="comment">// a quick way to 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</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">// C-style variadics detection (e.g. an ellipses in a signature)</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</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="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="comment">// <code class="literal">callable_traits::</code>can_invoke allows us to preview whether</span>
<span class="comment">// std::invoke would compile with the given arguments.</span>
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">can_invoke</span><span class="special">(</span><span class="identifier">foo</span><span class="special">{},</span> <span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">i</span><span class="special">),</span> <span class="string">""</span><span class="special">);</span>
<span class="comment">// no error: std::invoke(foo{}, 0, 0, i);</span>
<span class="comment">// This call returns std::false_type, because it's an illegal call.</span>
<span class="keyword">static_assert</span><span class="special">(!</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">can_invoke</span><span class="special">(</span><span class="identifier">foo</span><span class="special">{},</span> <span class="keyword">nullptr</span><span class="special">),</span> <span class="string">""</span><span class="special">);</span>
<span class="comment">// error: std::invoke(foo{}, nullptr);</span>
<span class="comment">// Note that since can_invoke models std::invoke,</span>
<span class="comment">// only a value-style function is defined.</span>
<span class="comment">// For function objects, the following checks are determined by the</span>
<span class="comment">// function qualifiers on operator(), rather than the qualifiers on</span>
<span class="comment">// of the type passed. This is done for consistency with member function</span>
<span class="comment">// pointers, where the checks below would look at the function qualifiers</span>
<span class="comment">// (rather than qualifiers on the pointer itself).</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</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="keyword">static_assert</span><span class="special">(!</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">is_volatile_member</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="keyword">static_assert</span><span class="special">(!</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">is_reference_member</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="keyword">static_assert</span><span class="special">(!</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">is_lvalue_reference_member</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="keyword">static_assert</span><span class="special">(!</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">is_rvalue_reference_member</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">// is_constexpr would return std::true_type if foo's operator() were constexpr.</span>
<span class="keyword">static_assert</span><span class="special">(!</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">is_constexpr</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">// The same check can be performed using std::integral_constant</span>
<span class="comment">// in conjunction with function addresses:</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="keyword">using</span> <span class="identifier">pmf_constant</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">integral_constant</span><span class="special">&lt;</span><span class="identifier">pmf</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">foo</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()&gt;;</span>
<span class="keyword">static_assert</span><span class="special">(!</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">is_constexpr</span><span class="special">&lt;</span><span class="identifier">pmf_constant</span><span class="special">&gt;(),</span> <span class="string">""</span><span class="special">);</span>
<span class="comment">// So that you don't have to scroll to the top to check,</span>
<span class="comment">// here's the type of pmf for reference.</span>
<span class="keyword">using</span> <span class="identifier">with_const</span> <span class="special">=</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">int</span><span class="special">&amp;&amp;,</span> <span class="keyword">const</span> <span class="keyword">int</span><span class="special">&amp;,</span> <span class="keyword">void</span><span class="special">*)</span> <span class="keyword">const</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">pmf</span><span class="special">,</span> <span class="identifier">with_const</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="comment">// If you find yourself in the unfortunate-and-probably-avoidable</span>
<span class="comment">// situation of needing to transform member function pointer</span>
<span class="comment">// types, <code class="literal">CallableTraits</code> has all the tools you need to prolong</span>
<span class="comment">// your sanity.</span>
<span class="comment">// <code class="literal">CallableTraits</code> lets you manipulate qualifiers on PMF types.</span>
<span class="comment">// To remove const:</span>
<span class="keyword">using</span> <span class="identifier">mutable_pmf</span> <span class="special">=</span> <span class="identifier">ct</span><span class="special">::</span><span class="identifier">remove_member_const</span><span class="special">&lt;</span><span class="identifier">pmf</span><span class="special">&gt;;</span>
<span class="keyword">using</span> <span class="identifier">without_const</span> <span class="special">=</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">int</span><span class="special">&amp;&amp;,</span> <span class="keyword">const</span> <span class="keyword">int</span><span class="special">&amp;,</span> <span class="keyword">void</span><span class="special">*)</span> <span class="comment">/*no const!*/</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">mutable_pmf</span><span class="special">,</span> <span class="identifier">without_const</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="comment">// To add an rvalue qualifier:</span>
<span class="keyword">using</span> <span class="identifier">rvalue_pmf</span> <span class="special">=</span> <span class="identifier">ct</span><span class="special">::</span><span class="identifier">add_member_rvalue_reference</span><span class="special">&lt;</span><span class="identifier">pmf</span><span class="special">&gt;;</span>
<span class="keyword">using</span> <span class="identifier">with_rvalue</span> <span class="special">=</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">int</span><span class="special">&amp;&amp;,</span> <span class="keyword">const</span> <span class="keyword">int</span><span class="special">&amp;,</span> <span class="keyword">void</span><span class="special">*)</span> <span class="keyword">const</span> <span class="special">&amp;&amp;;</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">rvalue_pmf</span><span class="special">,</span> <span class="identifier">with_rvalue</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="comment">// Just like std::add_rvalue_reference, <code class="literal">callable_traits::</code>add_member_rvalue_reference</span>
<span class="comment">// follows C++11 reference collapsing rules. While remove_member_const</span>
<span class="comment">// and add_member_rvalue_reference are somewhat clumsy names, they are the best</span>
<span class="comment">// the best the author could provide while still allowing both terseness</span>
<span class="comment">// and grep-ability against std::remove_const, etc. in &lt;type_traits&gt;.</span>
<span class="comment">// Naturally, <code class="literal">CallableTraits</code> provides similar tools for the other C++</span>
<span class="comment">// function qualifiers. Head to the reference section of this documentation</span>
<span class="comment">// for more examples.</span>
<span class="comment">// To remove a member pointer:</span>
<span class="keyword">using</span> <span class="identifier">fn</span> <span class="special">=</span> <span class="identifier">ct</span><span class="special">::</span><span class="identifier">remove_member_pointer</span><span class="special">&lt;</span><span class="identifier">pmf</span><span class="special">&gt;;</span>
<span class="keyword">using</span> <span class="identifier">expected_fn</span> <span class="special">=</span> <span class="keyword">void</span> <span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&amp;&amp;,</span> <span class="keyword">const</span> <span class="keyword">int</span><span class="special">&amp;,</span> <span class="keyword">void</span><span class="special">*)</span> <span class="keyword">const</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">fn</span><span class="special">,</span> <span class="identifier">expected_fn</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="comment">// We just created an abominable function type - notice the const</span>
<span class="comment">// qualifier! namespace_scopedremove_member_const accepts abominable</span>
<span class="comment">// types too (and so does any feature where it is legal to do so):</span>
<span class="keyword">using</span> <span class="identifier">not_abominable</span> <span class="special">=</span> <span class="identifier">ct</span><span class="special">::</span><span class="identifier">remove_member_const</span><span class="special">&lt;</span><span class="identifier">fn</span><span class="special">&gt;;</span>
<span class="keyword">using</span> <span class="identifier">expected_fn2</span> <span class="special">=</span> <span class="keyword">void</span> <span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&amp;&amp;,</span> <span class="keyword">const</span> <span class="keyword">int</span><span class="special">&amp;,</span> <span class="keyword">void</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">not_abominable</span><span class="special">,</span> <span class="identifier">expected_fn2</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>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="callable_traits.introduction.reasons"></a><a class="link" href="index.html#callable_traits.introduction.reasons" title="What makes CallableTraits unique?">What makes <code class="literal">CallableTraits</code>
unique?</a>
</h3></div></div></div>
<p>
<span class="bold"><strong>1.</strong></span> <code class="literal">CallableTraits</code> offers
template aliases such as <a class="link" href="callable_traits/ref_remove_member_const.html" title="remove_member_const"><code class="literal">remove_member_const</code></a>
for manipulating function qualifiers, designed to parallel the <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">type_traits</span><span class="special">&gt;</span></code> aliases such as <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">remove_const_t</span></code>.
</p>
<p>
<span class="bold"><strong>2.</strong></span> <code class="literal">CallableTraits</code> is
designed to accept cv-qualified and ref-qualified types, which eliminates
the need to prepare template argument types with metafunctions such as <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">remove_reference</span></code>
and <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">decay</span></code>. This is especially useful when dealing
with perfectly-forwarded parameter types in function templates.
</p>
<p>
<span class="bold"><strong>3.</strong></span> <code class="literal">CallableTraits</code> is
designed to comply with <a href="http://en.cppreference.com/w/cpp/utility/functional/invoke" target="_top"><code class="literal"><span class="emphasis"><em>INVOKE</em></span></code></a>
rules, with one unobtrusive and beneficial deviation: <a class="link" href="callable_traits/concepts.html#callable_traits.concepts.ref_fn" title="Function"><span class="green">Function</span></a> types are compatible with all relevant
type operations that do not specifically require an invocation.
</p>
<p>
<span class="bold"><strong>4.</strong></span> <code class="literal">callable_traits::</code><a class="link" href="callable_traits/ref_arg_at.html" title="arg_at"><code class="literal">arg_at</code></a><code class="computeroutput"><span class="special">&lt;</span><span class="number">2</span><span class="special">,</span>
<span class="identifier">Callable</span><span class="special">&gt;</span></code>
is more flexible than <code class="computeroutput"><span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">function_traits</span><span class="special">&lt;</span><span class="identifier">Callable</span><span class="special">&gt;::</span><span class="identifier">arg3_type</span></code>.
</p>
<p>
<span class="bold"><strong>5.</strong></span> <a class="link" href="callable_traits/ref_can_invoke.html" title="can_invoke"><code class="literal">can_invoke</code></a>
is used to test <code class="computeroutput"><span class="identifier">INVOKE</span></code>-ability
at compile-time, with value semantics. For the craziest metaprogrammers,
<a class="link" href="callable_traits/ref_can_invoke_constexpr.html" title="can_invoke_constexpr"><code class="literal">can_invoke_constexpr</code></a>
does the same as <code class="computeroutput"><span class="identifier">can_invoke</span></code>
for <a class="link" href="callable_traits/concepts.html#callable_traits.concepts.ref_constexpr_constructible" title="ConstexprDefaultConstructible"><span class="green">ConstexprDefaultConstructible</span></a> types, with an
added check for <code class="computeroutput"><span class="keyword">constexpr</span></code>-ness
</p>
<p>
<span class="bold"><strong>6.</strong></span> <a class="link" href="callable_traits/ref_is_constexpr.html" title="is_constexpr"><code class="literal">is_constexpr</code></a>
is used to check whether a <a class="link" href="callable_traits/concepts.html#callable_traits.concepts.ref_constexpr_constructible" title="ConstexprDefaultConstructible"><span class="green">ConstexprDefaultConstructible</span></a> type is a <a class="link" href="callable_traits/concepts.html#callable_traits.concepts.ref_callable" title="Callable"><span class="green">Callable</span></a>
type that yields a <code class="computeroutput"><span class="keyword">constexpr</span></code>
result -- no arguments necessary.
</p>
<p>
<span class="bold"><strong>7.</strong></span> <a class="link" href="callable_traits/ref_bind.html" title="bind"><code class="literal">bind</code></a>
is used to intercept the signature information from a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">placeholder</span></code>
expression before forwarding on to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bind</span></code>
or <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span></code>. This gives library writers the power
to create more flexible template APIs for callable types.
</p>
<p>
<span class="bold"><strong>8.</strong></span> <a class="link" href="callable_traits/ref_min_arity.html" title="min_arity"><code class="literal">min_arity</code></a>
can be used to detect the presence of default arguments on a <a class="link" href="callable_traits/concepts.html#callable_traits.concepts.ref_simple_fn_obj" title="SimpleFunctionObject"><span class="green">SimpleFunctionObject</span></a>
</p>
<p>
<span class="bold"><strong>9.</strong></span> The <code class="literal">CallableTraits</code>
interface mainly consists of template aliases and <code class="computeroutput"><span class="keyword">constexpr</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">integral_constant</span></code> functions, which are
arguably preferable to <code class="computeroutput"><span class="keyword">typename</span> <span class="identifier">foo</span><span class="special">::</span><span class="identifier">type</span></code>
and <code class="computeroutput"><span class="identifier">foo</span><span class="special">::</span><span class="identifier">value</span></code>. While the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">integral_constant</span></code>
functions in <code class="literal">CallableTraits</code> may be a deviation from traditional
type trait designs, they facilitate a metaprogramming style that uses value-semantics
(a la <a href="https://boostorg.github.io/hana/" target="_top"><code class="literal">Boost.Hana</code></a>).
The functions can generally be used with either types or values, which eliminates
unnecessary <code class="computeroutput"><span class="keyword">decltype</span></code> usage.
</p>
<p>
<span class="bold"><strong>10.</strong></span> <code class="literal">CallableTraits</code> includes
optional features for the manipulation and inspection of calling conventions.
These features are currently deemed experimental, because they greatly increase
the test surface of <code class="literal">CallableTraits</code>, are platform-specific,
and are not yet fully tested on any platform.
</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/function_sugar_example.html"><img src="../src/images/next.png" alt="Next"></a></div>
</body>
</html>