Files
callable_traits/doc/html/index.html

505 lines
68 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/quick_example.html" title="Example: Overview">
</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/quick_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.boost_function_types">Regarding
<code class="literal">Boost.FunctionTypes</code></a></span></dt>
</dl></dd>
<dt><span class="section"><a href="callable_traits/quick_example.html">Example: Overview</a></span></dt>
<dt><span class="section"><a href="callable_traits/example_std_function_sugar.html">Example: std::function
sugar</a></span></dt>
<dt><span class="article"><a href="callable_traits_interface_example.html">Example: Java-style interfaces without inheritance</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.compatibility_issues">Known
Issues</a></span></dt></dl></dd>
<dt><span class="section"><a href="callable_traits/faq.html">FAQ</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="callable_traits/faq.html#callable_traits.faq.reasons">Why should I use <code class="literal">CallableTraits</code>?</a></span></dt>
<dt><span class="section"><a href="callable_traits/faq.html#callable_traits.faq.reasons0">What makes <code class="literal">CallableTraits</code>
unique?</a></span></dt>
<dt><span class="section"><a href="callable_traits/faq.html#callable_traits.faq.faq_function_types">Why not update
and extend <code class="literal">Boost.FunctionTypes</code> instead?</a></span></dt>
<dt><span class="section"><a href="callable_traits/faq.html#callable_traits.faq.why_does_namespace_scoped_args_a">Why
does <code class="literal">callable_traits::</code><code class="literal">args</code> alias a <code class="literal">std::tuple</code>?</a></span></dt>
<dt><span class="section"><a href="callable_traits/faq.html#callable_traits.faq.why_are_the_libname_alias_templa">Why
are the <code class="literal">CallableTraits</code> alias templates not suffixed with
<code class="computeroutput"><span class="identifier">_t</span></code>, as in <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">add_lvalue_reference_t</span></code>?</a></span></dt>
<dt><span class="section"><a href="callable_traits/faq.html#callable_traits.faq.why_use_constexpr_function_templ">Why
use constexpr function templates? Why not use something like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same</span></code>
or even <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same_v</span></code>?</a></span></dt>
<dt><span class="section"><a href="callable_traits/faq.html#callable_traits.faq.why_use_reference_collapsing_rul">Why
use reference collapsing rules when adding member function ref-qualifiers?</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="callable_traits/development.html">Development</a></span></dt>
<dd><dl><dt><span class="section"><a href="callable_traits/development.html#callable_traits.development.building">Building the test
suite</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>
<dd><dl>
<dt><span class="section"><a href="callable_traits/headers.html#callable_traits.headers.qualifiers">Qualifiers</a></span></dt>
<dt><span class="section"><a href="callable_traits/headers.html#callable_traits.headers.parameters">Parameters</a></span></dt>
<dt><span class="section"><a href="callable_traits/headers.html#callable_traits.headers.return_types">Return Types</a></span></dt>
<dt><span class="section"><a href="callable_traits/headers.html#callable_traits.headers.invoke"><span class="emphasis"><em>INVOKE</em></span></a></span></dt>
<dt><span class="section"><a href="callable_traits/headers.html#callable_traits.headers.member_pointers">Member Pointers</a></span></dt>
<dt><span class="section"><a href="callable_traits/headers.html#callable_traits.headers.constant_expressions">Constant
Expressions</a></span></dt>
<dt><span class="section"><a href="callable_traits/headers.html#callable_traits.headers.variadics">Variadics</a></span></dt>
<dt><span class="section"><a href="callable_traits/headers.html#callable_traits.headers.calling_conventions_experimental">Calling
Conventions (experimental)</a></span></dt>
</dl></dd>
<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_clear_args.html">clear_args</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_insert_args.html">insert_args</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_replace_args.html">replace_args</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_remove_args.html">remove_args</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_expand_args.html">expand_args</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_is_callable.html">is_callable</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_cv_member.html">is_cv_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_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_push_back.html">push_back</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_push_front.html">push_front</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_pop_back.html">pop_back</a></span></dt>
<dt><span class="section"><a href="callable_traits/ref_push_front0.html">pop_front</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.boost_function_types">Regarding
<code class="literal">Boost.FunctionTypes</code></a></span></dt>
</dl></div>
<p>
<code class="literal">CallableTraits</code> is a C++11/14/17 header-only library for
the inspection, synthesis, and decomposition of callable types. Whether it's
calling conventions, <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">volatile</span>
<span class="special">&amp;&amp;</span></code>, or container-like manipulation
of parameter lists, <code class="literal">CallableTraits</code> provides all the tools
you need to <span class="bold"><strong>completely rid your codebase of function
type specializations</strong></span>. While not for everyone, <code class="literal">CallableTraits</code>
offers a comprehensive, fine-grained assortment of traits and metafunctions
for building and ripping apart C++'s most complicated and obscure types with
ease. <code class="literal">CallableTraits</code> fills the gaps where existing library
solutions fall short, aiming to be the "complete type manipulation facility
for function types" mentioned in the last section of <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2015/p0172r0.html" target="_top">p0172</a>,
the C++17 proposal regarding "abominable function types". <code class="literal">CallableTraits</code>
currently supports GCC 4.8 and later, Clang 3.5 and later, AppleClang from
XCode 6.3 and later, and MSVC 19. <code class="literal">CallableTraits</code> is header-only,
and does not depend on any non-standard headers.
</p>
<p>
<code class="literal">CallableTraits</code> is currently hosted at <a href="https://github.com/badair/callable_traits" target="_top">GitHub</a>.
<span class="bold"><strong><code class="literal">CallableTraits</code> is not a Boost library.</strong></span>
</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>
A few features are disabled for older/non-compliant compilers. See the <a class="link" href="callable_traits/compatibility.html#callable_traits.compatibility.compatibility_issues" title="Known Issues">Compatibility
Issues</a> section for more details.
</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> (a.k.a. PMFs)
</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> (a.k.a. PMDs)
</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>
<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 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>
<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="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">?</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>
<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>
features for <a href="https://isocpp.org/files/papers/n4000.pdf" target="_top"><code class="literal">transaction_safe</code></a>
are planned, but not yet implemented.
</p></td></tr>
</table></div>
<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">
Each calling convention effectively doubles the test surface of <code class="literal">CallableTraits</code>
on every supported platform. Tests have not yet been written to account
for this.
</li>
<li class="listitem">
The author's knowledge of cross-platform behavior of calling conventions
in C++ is 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, please <a class="link" href="callable_traits/contact.html" title="Contact">contact the author</a>.
</p>
</td></tr>
</table></div>
</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> are closely related to
those of <a href="http://www.boost.org/doc/libs/1_60_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>:
</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 (except for platform-specific
calling conventions).
</li>
</ol></div>
<p>
By building on the achievements of others, <code class="literal">CallableTraits</code>
borrows and extends much of the functionality found in <code class="literal">Boost.FunctionTypes</code>,
re-packaging it in a 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>,
which is a great choice for projects already using the MPL, and for metaprogramming
on older compilers. However, an MPL sequence-based solution with no C++11
support should not be the only option for inspecting and manipulating callable
types.
</p>
<p>
See Also: <a class="link" href="callable_traits/faq.html#callable_traits.faq.faq_function_types" title="Why not update and extend Boost.FunctionTypes instead?">Why not
update and extend <code class="literal">Boost.FunctionTypes</code> instead?</a>
</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/quick_example.html"><img src="../src/images/next.png" alt="Next"></a></div>
</body>
</html>