mirror of
https://github.com/boostorg/callable_traits.git
synced 2026-02-17 13:42:14 +00:00
505 lines
68 KiB
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 © 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">&&</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">“<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>”</span></em></span></strong></span>
|
|
</p>
|
|
<p>
|
|
-- Stephan T. Lavavej, CppCon 2015, <a href="https://www.youtube.com/watch?v=zt7ThwVfap0&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"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></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"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&&></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&&></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&&></span> <span class="special">{};</span>
|
|
|
|
<span class="comment">//function type with varargs</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&&></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&&></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&&></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&&></span> <span class="special">{};</span>
|
|
|
|
<span class="comment">//member function pointer type without varargs</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&&></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&&></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&&></span> <span class="special">{};</span>
|
|
|
|
<span class="comment">//member function pointer type with varargs</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&&></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&&></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&&></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&></span> <span class="special">{};</span>
|
|
<span class="keyword">template</span><span class="special"><</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">></span> <span class="keyword">struct</span> <span class="identifier">foo</span><span class="special"><</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">&&></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"><type_traits></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>
|