mirror of
https://github.com/boostorg/callable_traits.git
synced 2026-02-10 23:32:20 +00:00
562 lines
86 KiB
HTML
562 lines
86 KiB
HTML
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
|
<title>CallableTraits</title>
|
|
<link rel="stylesheet" href="boostbook.css" type="text/css">
|
|
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
|
|
<link rel="home" href="index.html" title="CallableTraits">
|
|
<link rel="next" href="callable_traits/function_sugar_example.html" title="Example: std::function sugar">
|
|
</head>
|
|
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
|
<table cellpadding="2" width="100%"><tr>
|
|
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../boost.png"></td>
|
|
<td align="center"><a href="../../index.html">Home</a></td>
|
|
<td align="center"><a href="../../libs/libraries.htm">Libraries</a></td>
|
|
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
|
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
|
<td align="center"><a href="../../more/index.htm">More</a></td>
|
|
</tr></table>
|
|
<hr>
|
|
<div class="spirit-nav"><a accesskey="n" href="callable_traits/function_sugar_example.html"><img src="../src/images/next.png" alt="Next"></a></div>
|
|
<div lang="en" class="article">
|
|
<div class="titlepage">
|
|
<div>
|
|
<div><h2 class="title">
|
|
<a name="callable_traits"></a>CallableTraits</h2></div>
|
|
<div><div class="authorgroup"><div class="author"><h3 class="author">
|
|
<span class="firstname">Barrett</span> <span class="surname">Adair</span>
|
|
</h3></div></div></div>
|
|
<div><p class="copyright">Copyright © 2016 Barrett Adair</p></div>
|
|
<div><div class="legalnotice">
|
|
<a name="callable_traits.legal"></a><p>
|
|
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
file LICENSE.md or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
|
</p>
|
|
</div></div>
|
|
</div>
|
|
<hr>
|
|
</div>
|
|
<div class="toc">
|
|
<p><b>Table of Contents</b></p>
|
|
<dl class="toc">
|
|
<dt><span class="section"><a href="index.html#callable_traits.introduction">Introduction</a></span></dt>
|
|
<dd><dl>
|
|
<dt><span class="section"><a href="index.html#callable_traits.introduction.prereqs">Prerequisite Topics</a></span></dt>
|
|
<dt><span class="section"><a href="index.html#callable_traits.introduction.motivation">Motivation</a></span></dt>
|
|
<dt><span class="section"><a href="index.html#callable_traits.introduction.quick_example">Quick Example</a></span></dt>
|
|
</dl></dd>
|
|
<dt><span class="section"><a href="callable_traits/function_sugar_example.html">Example: <code class="literal">std::function</code>
|
|
sugar</a></span></dt>
|
|
<dt><span class="section"><a href="callable_traits/compatibility.html">Compatibility</a></span></dt>
|
|
<dd><dl><dt><span class="section"><a href="callable_traits/compatibility.html#callable_traits.compatibility.msvc_issues">MSVC Issues</a></span></dt></dl></dd>
|
|
<dt><span class="section"><a href="callable_traits/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.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/contact.html">Contact</a></span></dt>
|
|
<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_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_has_void_return.html">has_void_return</a></span></dt>
|
|
<dt><span class="section"><a href="callable_traits/ref_is_const_member.html">is_const_member</a></span></dt>
|
|
<dt><span class="section"><a href="callable_traits/ref_is_constexpr.html">is_constexpr</a></span></dt>
|
|
<dt><span class="section"><a href="callable_traits/ref_is_lvalue_reference_member.html">is_lvalue_reference_member</a></span></dt>
|
|
<dt><span class="section"><a href="callable_traits/ref_is_reference_member.html">is_reference_member</a></span></dt>
|
|
<dt><span class="section"><a href="callable_traits/ref_is_rvalue_reference_member.html">is_rvalue_reference_member</a></span></dt>
|
|
<dt><span class="section"><a href="callable_traits/ref_has_member_qualifiers.html">has_member_qualifiers</a></span></dt>
|
|
<dt><span class="section"><a href="callable_traits/ref_is_volatile_member.html">is_volatile_member</a></span></dt>
|
|
<dt><span class="section"><a href="callable_traits/ref_max_arity.html">max_arity</a></span></dt>
|
|
<dt><span class="section"><a href="callable_traits/ref_min_arity.html">min_arity</a></span></dt>
|
|
<dt><span class="section"><a href="callable_traits/ref_qualified_function_type.html">qualified_function_type</a></span></dt>
|
|
<dt><span class="section"><a href="callable_traits/ref_remove_calling_convention.html">remove_calling_convention</a></span></dt>
|
|
<dt><span class="section"><a href="callable_traits/ref_remove_member_const.html">remove_member_const</a></span></dt>
|
|
<dt><span class="section"><a href="callable_traits/ref_remove_member_cv.html">remove_member_cv</a></span></dt>
|
|
<dt><span class="section"><a href="callable_traits/ref_remove_member_pointer.html">remove_member_pointer</a></span></dt>
|
|
<dt><span class="section"><a href="callable_traits/ref_remove_member_reference.html">remove_member_reference</a></span></dt>
|
|
<dt><span class="section"><a href="callable_traits/ref_remove_varargs.html">remove_varargs</a></span></dt>
|
|
<dt><span class="section"><a href="callable_traits/ref_remove_member_volatile.html">remove_member_volatile</a></span></dt>
|
|
<dt><span class="section"><a href="callable_traits/ref_push_args_back.html">push_args_back</a></span></dt>
|
|
<dt><span class="section"><a href="callable_traits/ref_push_args_front.html">push_args_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>
|
|
</dl>
|
|
</div>
|
|
<div class="section">
|
|
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
|
<a name="callable_traits.introduction"></a><a class="link" href="index.html#callable_traits.introduction" title="Introduction">Introduction</a>
|
|
</h2></div></div></div>
|
|
<div class="toc"><dl class="toc">
|
|
<dt><span class="section"><a href="index.html#callable_traits.introduction.prereqs">Prerequisite Topics</a></span></dt>
|
|
<dt><span class="section"><a href="index.html#callable_traits.introduction.motivation">Motivation</a></span></dt>
|
|
<dt><span class="section"><a href="index.html#callable_traits.introduction.quick_example">Quick Example</a></span></dt>
|
|
</dl></div>
|
|
<p>
|
|
<code class="literal">CallableTraits</code> is a cross-platform C++14 library for the
|
|
inspection, decomposition, and synthesis of C++ callable types. <code class="literal">CallableTraits</code>
|
|
is header-only, and does not depend on any non-standard headers. <code class="literal">CallableTraits</code>
|
|
is currently hosted at <a href="https://github.com/badair/callable_traits" target="_top">GitHub</a>.
|
|
</p>
|
|
<div class="note"><table border="0" summary="Note">
|
|
<tr>
|
|
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../src/images/note.png"></td>
|
|
<th align="left">Note</th>
|
|
</tr>
|
|
<tr><td align="left" valign="top"><p>
|
|
<code class="literal">CallableTraits</code> is not a Boost library.
|
|
</p></td></tr>
|
|
</table></div>
|
|
<div class="section">
|
|
<div class="titlepage"><div><div><h3 class="title">
|
|
<a name="callable_traits.introduction.prereqs"></a><a class="link" href="index.html#callable_traits.introduction.prereqs" title="Prerequisite Topics">Prerequisite Topics</a>
|
|
</h3></div></div></div>
|
|
<p>
|
|
This documentation will be most beneficial to readers who posess a basic
|
|
understanding of the following C++ features:
|
|
</p>
|
|
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
|
<li class="listitem">
|
|
<a href="http://en.cppreference.com/w/cpp/language/partial_specialization" target="_top">template
|
|
specializations</a>
|
|
</li>
|
|
<li class="listitem">
|
|
<a href="http://en.cppreference.com/w/cpp/language/sfinae" target="_top">SFINAE</a>
|
|
</li>
|
|
<li class="listitem">
|
|
<a href="http://en.cppreference.com/w/cpp/utility/functional/invoke" target="_top"><code class="literal"><span class="emphasis"><em>INVOKE</em></span></code></a>
|
|
rules
|
|
</li>
|
|
<li class="listitem">
|
|
function types
|
|
</li>
|
|
<li class="listitem">
|
|
<a href="http://en.cppreference.com/w/cpp/language/pointer#Pointers_to_functions" target="_top">function
|
|
pointers</a>
|
|
</li>
|
|
<li class="listitem">
|
|
<a href="http://stackoverflow.com/questions/480248/function-references" target="_top">function
|
|
references</a>
|
|
</li>
|
|
<li class="listitem">
|
|
<a href="http://en.cppreference.com/w/cpp/language/pointer#Pointers_to_member_functions" target="_top">pointers
|
|
to member functions</a> (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>
|
|
<div class="note"><table border="0" summary="Note">
|
|
<tr>
|
|
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../src/images/note.png"></td>
|
|
<th align="left">Note</th>
|
|
</tr>
|
|
<tr><td align="left" valign="top"><p>
|
|
The upcoming ISO standard for C++17 includes a <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0012r1.html" target="_top">change
|
|
to the core language</a> which adds the <code class="literal">noexcept</code>
|
|
qualifier to the type system. If the author's understanding is correct,
|
|
this would increase the the count of necessary template specializations
|
|
to <span class="red"><span class="bold"><strong>96</strong></span></span> (<a class="link" href="callable_traits/contact.html" title="Contact">feedback</a>?). Currently, C++17
|
|
<code class="computeroutput"><span class="keyword">noexcept</span></code> qualifiers are not
|
|
handled in <code class="literal">CallableTraits</code>, because compiler vendors
|
|
have not implemented support for this feature (to best of the author's
|
|
knowledge). However, features to account for and manipulate <code class="computeroutput"><span class="keyword">noexcept</span></code> qualifiers are planned in <code class="literal">CallableTraits</code>,
|
|
as soon as feature is implemented by a compiler vendor. Of course, the
|
|
<code class="literal">CallableTraits</code> feature additions will be non-breaking
|
|
for currently supported compiler versions.
|
|
</p></td></tr>
|
|
</table></div>
|
|
<p>
|
|
Use cases for such obscure specializations are vitually nonexistent in run-of-the-mill
|
|
application codebases. Even in library code, these are exceedingly rare.
|
|
However, there are a handful of very specific metaprogramming scenarios that
|
|
can only be solved with such template "spam". While these use cases
|
|
are indeed rare, the writing and testing of these templates is incredibly
|
|
tedious and time consuming. On this premise, <code class="literal">CallableTraits</code>
|
|
offers a final and decisive library-level solution, so that authors of generic
|
|
code will <span class="bold"><strong>never again</strong></span> need to write these
|
|
specializations, for <span class="emphasis"><em>any</em></span> reason.
|
|
</p>
|
|
<p>
|
|
Template specializations like those in the code snippet above <span class="emphasis"><em>still</em></span>
|
|
do not account for function pointers, function references, function objects/lambdas,
|
|
or calling conventions. <code class="literal">CallableTraits</code> goes the extra
|
|
mile by accounting for all of them.
|
|
</p>
|
|
<div class="warning"><table border="0" summary="Warning">
|
|
<tr>
|
|
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../src/images/warning.png"></td>
|
|
<th align="left">Warning</th>
|
|
</tr>
|
|
<tr><td align="left" valign="top">
|
|
<p>
|
|
Features for the manipulation and inspection of calling conventions are
|
|
optional, which must be enabled with macro definitions. The features regarding
|
|
them are currently classified as <span class="emphasis"><em>experimental</em></span>, and
|
|
are subject to breaking changes in future versions of <code class="literal">CallableTraits</code>.
|
|
</p>
|
|
<p>
|
|
The rationale for classifying the calling convention features as "experimental"
|
|
is three-fold:
|
|
</p>
|
|
<div class="orderedlist"><ol class="orderedlist" type="1">
|
|
<li class="listitem">
|
|
Calling conventions are, by definition, highly platform-specific.
|
|
</li>
|
|
<li class="listitem">
|
|
The inclusion of a single calling convention effectively doubles the
|
|
test surface of <code class="literal">CallableTraits</code> <span class="emphasis"><em>on every
|
|
platform</em></span>.
|
|
</li>
|
|
<li class="listitem">
|
|
The author's current knowledge of calling conventions is admittedly
|
|
limited.
|
|
</li>
|
|
</ol></div>
|
|
<p>
|
|
It is the author's hope that future versions of <code class="literal">CallableTraits</code>
|
|
will offer a stable, thoroughly-tested, and well-documented implementation
|
|
of these features. If you have experience in this domain, your <a class="link" href="callable_traits/contact.html" title="Contact">feedback</a>
|
|
is <span class="emphasis"><em>highly</em></span> appreciated.
|
|
</p>
|
|
</td></tr>
|
|
</table></div>
|
|
<p>
|
|
The use cases for <code class="literal">CallableTraits</code> are closely related to
|
|
those of <a href="http://www.boost.org/doc/libs/1_60_0/libs/type_traits/doc/html/boost_typetraits/reference/function_traits.html" target="_top">function_traits</a>
|
|
and <a href="http://www.boost.org/doc/libs/1_60_0/libs/function_types/doc/html/index.html" target="_top">Boost.FunctionTypes</a>.
|
|
</p>
|
|
</div>
|
|
<div class="section">
|
|
<div class="titlepage"><div><div><h3 class="title">
|
|
<a name="callable_traits.introduction.quick_example"></a><a class="link" href="index.html#callable_traits.introduction.quick_example" title="Quick Example">Quick Example</a>
|
|
</h3></div></div></div>
|
|
<p>
|
|
This short program showcases some, but not all, of the features available
|
|
in <code class="literal">CallableTraits</code>.
|
|
</p>
|
|
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">type_traits</span><span class="special">></span>
|
|
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">functional</span><span class="special">></span>
|
|
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">tuple</span><span class="special">></span>
|
|
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">callable_traits</span><span class="special">/</span><span class="identifier">callable_traits</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
|
|
|
<span class="keyword">namespace</span> <span class="identifier">ct</span> <span class="special">=</span> <span class="identifier">callable_traits</span><span class="special">;</span>
|
|
|
|
<span class="comment">// foo is an example of a function object</span>
|
|
<span class="keyword">struct</span> <span class="identifier">foo</span> <span class="special">{</span>
|
|
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&&,</span> <span class="keyword">const</span> <span class="keyword">int</span><span class="special">&,</span> <span class="keyword">void</span><span class="special">*</span> <span class="special">=</span> <span class="keyword">nullptr</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{}</span>
|
|
<span class="special">};</span>
|
|
|
|
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
|
|
|
<span class="comment">// indexed argument types</span>
|
|
<span class="keyword">using</span> <span class="identifier">second_arg</span> <span class="special">=</span> <span class="identifier">ct</span><span class="special">::</span><span class="identifier">arg_at</span><span class="special"><</span><span class="number">1</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">>;</span>
|
|
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same</span><span class="special"><</span><span class="identifier">second_arg</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&&>::</span><span class="identifier">value</span><span class="special">,</span> <span class="string">""</span><span class="special">);</span>
|
|
|
|
<span class="comment">// arg types are packaged into std::tuple, which serves as the default</span>
|
|
<span class="comment">// type list in <code class="literal">CallableTraits</code> (runtime capabilities are not used).</span>
|
|
<span class="keyword">using</span> <span class="identifier">args</span> <span class="special">=</span> <span class="identifier">ct</span><span class="special">::</span><span class="identifier">args</span><span class="special"><</span><span class="identifier">foo</span><span class="special">>;</span>
|
|
<span class="keyword">using</span> <span class="identifier">expected_args</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special"><</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&&,</span> <span class="keyword">const</span> <span class="keyword">int</span><span class="special">&,</span> <span class="keyword">void</span><span class="special">*>;</span>
|
|
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same</span><span class="special"><</span><span class="identifier">args</span><span class="special">,</span> <span class="identifier">expected_args</span><span class="special">>::</span><span class="identifier">value</span><span class="special">,</span> <span class="string">""</span><span class="special">);</span>
|
|
|
|
<span class="comment">// <code class="literal">callable_traits::</code>function_type "decays" a callable type to a plain</span>
|
|
<span class="comment">// function type, which is structured in terms of INVOKE.</span>
|
|
<span class="keyword">using</span> <span class="identifier">function_type</span> <span class="special">=</span> <span class="identifier">ct</span><span class="special">::</span><span class="identifier">function_type</span><span class="special"><</span><span class="identifier">foo</span><span class="special">>;</span>
|
|
<span class="keyword">using</span> <span class="identifier">expected_function_type</span> <span class="special">=</span> <span class="keyword">void</span><span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&&,</span> <span class="keyword">const</span> <span class="keyword">int</span><span class="special">&,</span> <span class="keyword">void</span><span class="special">*);</span>
|
|
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same</span><span class="special"><</span><span class="identifier">function_type</span><span class="special">,</span> <span class="identifier">expected_function_type</span><span class="special">>::</span><span class="identifier">value</span><span class="special">,</span> <span class="string">""</span><span class="special">);</span>
|
|
|
|
<span class="comment">// By design, the <code class="literal">CallableTraits</code> interface uses constexpr</span>
|
|
<span class="comment">// std::integral_constant functions (whenever sensible).</span>
|
|
<span class="comment">// By also defining the appropriate overloads, this gives</span>
|
|
<span class="comment">// users the option of using either type arguments or a value</span>
|
|
<span class="comment">// arguments, which often eliminates the need for decltype:</span>
|
|
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">arity</span><span class="special"><</span><span class="identifier">foo</span><span class="special">>()</span> <span class="special">==</span> <span class="number">4</span><span class="special">,</span> <span class="string">""</span><span class="special">);</span>
|
|
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">arity</span><span class="special">(</span><span class="identifier">foo</span><span class="special">{})</span> <span class="special">==</span> <span class="number">4</span><span class="special">,</span> <span class="string">""</span><span class="special">);</span>
|
|
|
|
<span class="comment">// Attentive readers might notice that the type of the foo{}</span>
|
|
<span class="comment">// expression above is foo&&, rather than foo. Indeed,</span>
|
|
<span class="comment">// <code class="literal">CallableTraits</code> is designed to also allow both ref-qualified</span>
|
|
<span class="comment">// and cv-qualified arguments across the board:</span>
|
|
|
|
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">arity</span><span class="special"><</span><span class="identifier">foo</span><span class="special">&&>()</span> <span class="special">==</span> <span class="number">4</span><span class="special">,</span> <span class="string">""</span><span class="special">);</span>
|
|
|
|
<span class="comment">// Now, if foo had an operator() overload with a && qualifier, taking</span>
|
|
<span class="comment">// a different number of arguments, the above static assert would fail.</span>
|
|
|
|
<span class="comment">// For consistency, we'll avoid the value-style overloads</span>
|
|
<span class="comment">// for the remainder of this example (whenever possible).</span>
|
|
|
|
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">max_arity</span><span class="special"><</span><span class="identifier">foo</span><span class="special">>()</span> <span class="special">==</span> <span class="number">4</span><span class="special">,</span> <span class="string">""</span><span class="special">);</span>
|
|
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">min_arity</span><span class="special"><</span><span class="identifier">foo</span><span class="special">>()</span> <span class="special">==</span> <span class="number">3</span><span class="special">,</span> <span class="string">""</span><span class="special">);</span>
|
|
|
|
<span class="comment">// a quick way to check for a void return type</span>
|
|
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">has_void_return</span><span class="special"><</span><span class="identifier">foo</span><span class="special">>(),</span> <span class="string">""</span><span class="special">);</span>
|
|
|
|
<span class="comment">// C-style variadics detection (e.g. an ellipses in a signature)</span>
|
|
<span class="keyword">static_assert</span><span class="special">(!</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">has_varargs</span><span class="special"><</span><span class="identifier">foo</span><span class="special">>(),</span> <span class="string">""</span><span class="special">);</span>
|
|
|
|
<span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
|
|
|
|
<span class="comment">// <code class="literal">callable_traits::</code>can_invoke allows us to preview whether</span>
|
|
<span class="comment">// std::invoke would compile with the given arguments.</span>
|
|
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">can_invoke</span><span class="special">(</span><span class="identifier">foo</span><span class="special">{},</span> <span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">i</span><span class="special">),</span> <span class="string">""</span><span class="special">);</span>
|
|
<span class="comment">// no error: std::invoke(foo{}, 0, 0, i);</span>
|
|
|
|
<span class="comment">// This call returns std::false_type, because it's an illegal call.</span>
|
|
<span class="keyword">static_assert</span><span class="special">(!</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">can_invoke</span><span class="special">(</span><span class="identifier">foo</span><span class="special">{},</span> <span class="keyword">nullptr</span><span class="special">),</span> <span class="string">""</span><span class="special">);</span>
|
|
<span class="comment">// error: std::invoke(foo{}, nullptr);</span>
|
|
|
|
<span class="comment">// Note that since can_invoke models std::invoke,</span>
|
|
<span class="comment">// only a value-style function is defined.</span>
|
|
|
|
<span class="comment">// For function objects, the following checks are determined by the</span>
|
|
<span class="comment">// function qualifiers on operator(), rather than the qualifiers on</span>
|
|
<span class="comment">// of the type passed. This is done for consistency with member function</span>
|
|
<span class="comment">// pointers, where the checks below would look at the function qualifiers</span>
|
|
<span class="comment">// (rather than qualifiers on the pointer itself).</span>
|
|
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">is_const_member</span><span class="special"><</span><span class="identifier">foo</span><span class="special">>(),</span> <span class="string">""</span><span class="special">);</span>
|
|
<span class="keyword">static_assert</span><span class="special">(!</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">is_volatile_member</span><span class="special"><</span><span class="identifier">foo</span><span class="special">>(),</span> <span class="string">""</span><span class="special">);</span>
|
|
<span class="keyword">static_assert</span><span class="special">(!</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">is_reference_member</span><span class="special"><</span><span class="identifier">foo</span><span class="special">>(),</span> <span class="string">""</span><span class="special">);</span>
|
|
<span class="keyword">static_assert</span><span class="special">(!</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">is_lvalue_reference_member</span><span class="special"><</span><span class="identifier">foo</span><span class="special">>(),</span> <span class="string">""</span><span class="special">);</span>
|
|
<span class="keyword">static_assert</span><span class="special">(!</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">is_rvalue_reference_member</span><span class="special"><</span><span class="identifier">foo</span><span class="special">>(),</span> <span class="string">""</span><span class="special">);</span>
|
|
|
|
<span class="comment">// is_constexpr would return std::true_type if foo's operator() were constexpr.</span>
|
|
<span class="keyword">static_assert</span><span class="special">(!</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">is_constexpr</span><span class="special"><</span><span class="identifier">foo</span><span class="special">>(),</span> <span class="string">""</span><span class="special">);</span>
|
|
|
|
<span class="comment">// The same check can be performed using std::integral_constant</span>
|
|
<span class="comment">// in conjunction with function addresses:</span>
|
|
<span class="keyword">using</span> <span class="identifier">pmf</span> <span class="special">=</span> <span class="keyword">decltype</span><span class="special">(&</span><span class="identifier">foo</span><span class="special">::</span><span class="keyword">operator</span><span class="special">());</span>
|
|
<span class="keyword">using</span> <span class="identifier">pmf_constant</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">integral_constant</span><span class="special"><</span><span class="identifier">pmf</span><span class="special">,</span> <span class="special">&</span><span class="identifier">foo</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()>;</span>
|
|
<span class="keyword">static_assert</span><span class="special">(!</span><span class="identifier">ct</span><span class="special">::</span><span class="identifier">is_constexpr</span><span class="special"><</span><span class="identifier">pmf_constant</span><span class="special">>(),</span> <span class="string">""</span><span class="special">);</span>
|
|
|
|
<span class="comment">// So that you don't have to scroll to the top to check,</span>
|
|
<span class="comment">// here's the type of pmf for reference.</span>
|
|
<span class="keyword">using</span> <span class="identifier">with_const</span> <span class="special">=</span> <span class="keyword">void</span> <span class="special">(</span><span class="identifier">foo</span><span class="special">::*)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&&,</span> <span class="keyword">const</span> <span class="keyword">int</span><span class="special">&,</span> <span class="keyword">void</span><span class="special">*)</span> <span class="keyword">const</span><span class="special">;</span>
|
|
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same</span><span class="special"><</span><span class="identifier">pmf</span><span class="special">,</span> <span class="identifier">with_const</span><span class="special">>::</span><span class="identifier">value</span><span class="special">,</span> <span class="string">""</span><span class="special">);</span>
|
|
|
|
<span class="comment">// If you find yourself in the unfortunate-and-probably-avoidable</span>
|
|
<span class="comment">// situation of needing to transform member function pointer</span>
|
|
<span class="comment">// types, <code class="literal">CallableTraits</code> has all the tools you need to prolong</span>
|
|
<span class="comment">// your sanity.</span>
|
|
|
|
<span class="comment">// <code class="literal">CallableTraits</code> lets you manipulate qualifiers on PMF types.</span>
|
|
<span class="comment">// To remove const:</span>
|
|
<span class="keyword">using</span> <span class="identifier">mutable_pmf</span> <span class="special">=</span> <span class="identifier">ct</span><span class="special">::</span><span class="identifier">remove_member_const</span><span class="special"><</span><span class="identifier">pmf</span><span class="special">>;</span>
|
|
<span class="keyword">using</span> <span class="identifier">without_const</span> <span class="special">=</span> <span class="keyword">void</span> <span class="special">(</span><span class="identifier">foo</span><span class="special">::*)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&&,</span> <span class="keyword">const</span> <span class="keyword">int</span><span class="special">&,</span> <span class="keyword">void</span><span class="special">*)</span> <span class="comment">/*no const!*/</span><span class="special">;</span>
|
|
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same</span><span class="special"><</span><span class="identifier">mutable_pmf</span><span class="special">,</span> <span class="identifier">without_const</span><span class="special">>::</span><span class="identifier">value</span><span class="special">,</span> <span class="string">""</span><span class="special">);</span>
|
|
|
|
<span class="comment">// To add an rvalue qualifier:</span>
|
|
<span class="keyword">using</span> <span class="identifier">rvalue_pmf</span> <span class="special">=</span> <span class="identifier">ct</span><span class="special">::</span><span class="identifier">add_member_rvalue_reference</span><span class="special"><</span><span class="identifier">pmf</span><span class="special">>;</span>
|
|
<span class="keyword">using</span> <span class="identifier">with_rvalue</span> <span class="special">=</span> <span class="keyword">void</span> <span class="special">(</span><span class="identifier">foo</span><span class="special">::*)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&&,</span> <span class="keyword">const</span> <span class="keyword">int</span><span class="special">&,</span> <span class="keyword">void</span><span class="special">*)</span> <span class="keyword">const</span> <span class="special">&&;</span>
|
|
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same</span><span class="special"><</span><span class="identifier">rvalue_pmf</span><span class="special">,</span> <span class="identifier">with_rvalue</span><span class="special">>::</span><span class="identifier">value</span><span class="special">,</span> <span class="string">""</span><span class="special">);</span>
|
|
|
|
<span class="comment">// Just like std::add_rvalue_reference, <code class="literal">callable_traits::</code>add_member_rvalue_reference</span>
|
|
<span class="comment">// follows C++11 reference collapsing rules. While remove_member_const</span>
|
|
<span class="comment">// and add_member_rvalue_reference are somewhat clumsy names, they are the best</span>
|
|
<span class="comment">// the best the author could provide while still allowing both terseness</span>
|
|
<span class="comment">// and grep-ability against std::remove_const, etc. in <type_traits>.</span>
|
|
<span class="comment">// Naturally, <code class="literal">CallableTraits</code> provides similar tools for the other C++</span>
|
|
<span class="comment">// function qualifiers. Head to the reference section of this documentation</span>
|
|
<span class="comment">// for more examples.</span>
|
|
|
|
<span class="comment">// To remove a member pointer:</span>
|
|
<span class="keyword">using</span> <span class="identifier">fn</span> <span class="special">=</span> <span class="identifier">ct</span><span class="special">::</span><span class="identifier">remove_member_pointer</span><span class="special"><</span><span class="identifier">pmf</span><span class="special">>;</span>
|
|
<span class="keyword">using</span> <span class="identifier">expected_fn</span> <span class="special">=</span> <span class="keyword">void</span> <span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&&,</span> <span class="keyword">const</span> <span class="keyword">int</span><span class="special">&,</span> <span class="keyword">void</span><span class="special">*)</span> <span class="keyword">const</span><span class="special">;</span>
|
|
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same</span><span class="special"><</span><span class="identifier">fn</span><span class="special">,</span> <span class="identifier">expected_fn</span><span class="special">>::</span><span class="identifier">value</span><span class="special">,</span> <span class="string">""</span><span class="special">);</span>
|
|
|
|
<span class="comment">// We just created an abominable function type - notice the const</span>
|
|
<span class="comment">// qualifier! namespace_scopedremove_member_const accepts abominable</span>
|
|
<span class="comment">// types too (and so does any feature where it is legal to do so):</span>
|
|
<span class="keyword">using</span> <span class="identifier">not_abominable</span> <span class="special">=</span> <span class="identifier">ct</span><span class="special">::</span><span class="identifier">remove_member_const</span><span class="special"><</span><span class="identifier">fn</span><span class="special">>;</span>
|
|
<span class="keyword">using</span> <span class="identifier">expected_fn2</span> <span class="special">=</span> <span class="keyword">void</span> <span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&&,</span> <span class="keyword">const</span> <span class="keyword">int</span><span class="special">&,</span> <span class="keyword">void</span><span class="special">*);</span>
|
|
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same</span><span class="special"><</span><span class="identifier">not_abominable</span><span class="special">,</span> <span class="identifier">expected_fn2</span><span class="special">>::</span><span class="identifier">value</span><span class="special">,</span> <span class="string">""</span><span class="special">);</span>
|
|
<span class="special">}</span>
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
|
<td align="left"></td>
|
|
<td align="right"><div class="copyright-footer"></div></td>
|
|
</tr></table>
|
|
<hr>
|
|
<div class="spirit-nav"><a accesskey="n" href="callable_traits/function_sugar_example.html"><img src="../src/images/next.png" alt="Next"></a></div>
|
|
</body>
|
|
</html>
|