1[article CallableTraits 2 [quickbook 1.6] 3 [id callable_traits] 4 [copyright 2016-2018 Barrett Adair] 5 [authors [Adair, Barrett]] 6 [license 7 Distributed under the Boost Software License, Version 1.0. 8 (See accompanying file LICENSE.md or copy at 9 [@http://www.boost.org/LICENSE_1_0.txt http://www.boost.org/LICENSE_1_0.txt]) 10 ] 11 [source-mode c++] 12 [last-revision $Date$] 13 [lang en] 14] 15 16[/ developer: you should enable word wrap before you read further] 17 18[template libname[][^Boost.CallableTraits]] 19[template lib_namespace[][^callable_traits]] 20[template namespace_scoped[][^boost::callable_traits::]] 21[template header_include_prefix[]callable_traits/] 22[template invoke[][@http://en.cppreference.com/w/cpp/utility/functional/invoke [^['INVOKE]]]] 23[template hana[][@https://boostorg.github.io/hana/ [^Boost.Hana]]] 24[template feedback[][link callable_traits.contact feedback]] 25[template unsure[][link callable_traits.contact ?]] 26[template link_contact_the_author[][link callable_traits.contact contact me]] 27[template repo[][@https://github.com/boostorg/callable_traits GitHub]] 28[template abominable_paper[][@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0172r0.html "abominable" function types]] 29[template link_compatibility[][link callable_traits.compatibility Compatibility]] 30[template link_compatibility_issues[][link callable_traits.compatibility.compatibility_issues Compatibility Issues]] 31[template function_types_link[][@http://www.boost.org/doc/libs/1_61_0/libs/function_types/doc/html/index.html [^Boost.FunctionTypes]]] 32[template function_types[][^Boost.FunctionTypes]] 33 34[section:introduction Overview] 35 36[libname] is a C++11 header-only library for the inspection, synthesis, and decomposition of callable types. [libname] aims to be the "complete type manipulation facility for function types" mentioned in the final paragraph of C++17 proposal [@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2015/p0172r0.html p0172], and removes the need for template specializations for different function signatures. C++17 `noexcept` and the Transactional Memory TS are also supported if available. 37[import ../example/intro.cpp] 38[intro] 39 40[section:motivation Motivation] 41 42[:[*['["Don't try to write helper code to detect PMFs/PMDs and dispatch on them -- it is an [_absolute nightmare]. PMF types are the worst types by far in the core language.]]] 43 44-- Stephan T. Lavavej, CppCon 2015, [@https://www.youtube.com/watch?v=zt7ThwVfap0&t=11m40s "functional: What's New, And Proper Usage"] 45] 46 47Consider for a moment the code below, which defines all 48 template specializations necessary to specialize for every valid function type in pure C++17: 48 49[import ./hideous_template.snippet.cpp] 50[hideous_template] 51 52Things get even more complicated with member function pointers, function pointers, function references, function objects, and `transaction_safe`. 53 54Granted, 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 metaprogramming scenarios that can only be solved with this kind of template "spam". Writing, testing, and maintaining such code is tedious and costly. 55 56[libname] offers a final and decisive library-level solution to this problem, and removes the need for these specializations entirely (platform-specific calling conventions notwithstanding). 57 58[endsect][/section:motivation] 59 60[section:boost_function_types Regarding [^Boost.FunctionTypes]] 61 62The features in [libname] largely overlap with [function_types_link]. Here are some reasons why you might prefer [libname]: 63 64# [function_types] is tightly coupled to [@http://www.boost.org/doc/libs/1_64_0/libs/mpl/doc/index.html [^Boost.MPL]] sequences, while [libname] has no dependencies other than the standard library. 65# [libname] targets C++11 and later: 66 # [libname] treats function objects/lambdas as first-class citizens. 67 # [libname] supports lvalue/rvalue reference member qualifiers. 68 # [libname] supports `noexcept` and `transaction_safe`. 69# [function_types] does not attempt to factor all callable types into a unified, [invoke]-aware interface. 70# [function_types] relies heavily on "tag" types, while [libname] follows the style of <type_traits> instead. Supporting C++11 and later in [function_types] would have required significant proliferation of these tags. 71 72For example, here is how to remove member `const` from a member function pointer type in the [function_types] library: 73 74 #include <type_traits> 75 #include <boost/function_types/components.hpp> 76 #include <boost/function_types/member_function_pointer.hpp> 77 78 struct foo { 79 void bar() const {} 80 }; 81 82 using const_removed = typename boost::function_types::member_function_pointer< 83 typename boost::function_types::components<decltype(&foo::bar)>::types, 84 boost::function_types::non_const>::type; 85 86 static_assert(std::is_same<const_removed, void(foo::*)()>::value, ""); 87 88 int main(){} 89 90[libname] makes this easier: 91 92[import ../example/function_types_remove_const_comparison.cpp] 93[function_types_remove_const_comparison] 94 95The [function_types] library includes an excellent [@http://www.boost.org/doc/libs/1_64_0/libs/function_types/example/interface_example.cpp example] for generating type-erased interfaces (implementation [@http://www.boost.org/doc/libs/1_64_0/libs/function_types/example/interface.hpp here]). This example was [@https://github.com/badair/eraserface/blob/master/include/eraserface/eraserface.hpp re-implemented] using [libname] to yield a [@https://github.com/badair/eraserface/blob/master/example/basic_example.cpp slightly more intuitive interface]. 96 97[function_types] is a fine library, but its interface left room for improvement. 98 99[endsect][/section:boost_function_types] 100 101[section:compatibility Compatibility] 102 103[template link_travis_ci[][@https://travis-ci.org/boostorg/callable_traits/builds Travis]] 104[template link_appveyor_ci[][@https://ci.appveyor.com/project/boostorg/callable-traits Appveyor]] 105 106[libname] supports on GCC 4.7.4+, Clang 3.5.2+, XCode 6.4+, and Visual Studio 2015+. Continuous integration is managed on [link_appveyor_ci] for Visual Studio, and on [link_travis_ci] for everything else. The Intel C++ Compiler is not officially supported yet, although the 2017 version for Linux does pass a handful of test cases. 107 108[template yes[][role green \u2713]] 109[template c11[][role green c++11]] 110[template c14[][role green c++14]] 111[template c17[][role green c++17]] 112[template gnutm[][role gold c++17] (requires -fgnu-tm)] 113[template noabom[][role gold c++11] (no abominables)] 114[template no[][role red static_assert fails on instantiation]] 115[template falsy[][role gold c++11] (always false)] 116[template noop[][role gold c++11] (no effect)] 117[template unk[]unknown] 118 119[table GCC Support 120 [[feature] [GCC 8.2.0] [GCC 7.3.0] [GCC 6.3.0] [GCC 5.4.0] [GCC 4.9.2] [GCC 4.8.2] [GCC 4.7.4]] 121 [[[link callable_traits.reference.ref_add_member_const [^add_member_const]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[noabom]] [[noabom]] ] 122 [[[link callable_traits.reference.ref_add_member_cv [^add_member_cv]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[noabom]] [[noabom]] ] 123 [[[link callable_traits.reference.ref_add_member_lvalue_reference [^add_member_lvalue_reference]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[no]] [[no]] ] 124 [[[link callable_traits.reference.ref_add_member_rvalue_reference [^add_member_rvalue_reference]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[no]] [[no]] ] 125 [[[link callable_traits.reference.ref_add_member_volatile [^add_member_volatile]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[noabom]] [[noabom]] ] 126 [[[link callable_traits.reference.ref_add_noexcept [^add_noexcept]]] [[c17]] [[c17]] [[c17]] [[no]] [[no]] [[no]] [[no]] ] 127 [[[link callable_traits.reference.ref_add_transaction_safe [^add_transaction_safe]]] [[gnutm]] [[gnutm]] [[gnutm]] [[no]] [[no]] [[no]] [[no]] ] 128 [[[link callable_traits.reference.ref_add_varargs [^add_varargs]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 129 [[[link callable_traits.reference.ref_apply_member_pointer [^apply_member_pointer]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 130 [[[link callable_traits.reference.ref_apply_return [^apply_return]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 131 [[[link callable_traits.reference.ref_args [^args]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 132 [[[link callable_traits.reference.ref_class_of [^class_of]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 133 [[[link callable_traits.reference.ref_function_type [^function_type]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 134 [[[link callable_traits.reference.ref_has_member_qualifiers [^has_member_qualifiers]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[noabom]] [[noabom]] ] 135 [[[link callable_traits.reference.ref_has_varargs [^has_varargs]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 136 [[[link callable_traits.reference.ref_has_void_return [^has_void_return]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 137 [[[link callable_traits.reference.ref_is_const_member [^is_const_member]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[noabom]] [[noabom]] ] 138 [[[link callable_traits.reference.ref_is_cv_member [^is_cv_member]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[noabom]] [[noabom]] ] 139 [[[link callable_traits.reference.ref_is_invocable [^is_invocable]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[unk]] [[unk]] ] 140 [[[link callable_traits.reference.ref_is_lvalue_reference_member [^is_lvalue_reference_member]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[falsy]] [[falsy]] ] 141 [[[link callable_traits.reference.ref_is_noexcept [^is_noexcept]]] [[c17]] [[c17]] [[c17]] [[falsy]] [[falsy]] [[falsy]] [[falsy]] ] 142 [[[link callable_traits.reference.ref_is_reference_member [^is_reference_member]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[falsy]] [[falsy]] ] 143 [[[link callable_traits.reference.ref_is_rvalue_reference_member [^is_rvalue_reference_member]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[falsy]] [[falsy]] ] 144 [[[link callable_traits.reference.ref_is_transaction_safe [^is_transaction_safe]]] [[gnutm]] [[gnutm]] [[gnutm]] [[falsy]] [[falsy]] [[falsy]] [[falsy]] ] 145 [[[link callable_traits.reference.ref_is_volatile_member [^is_volatile_member]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[noabom]] [[noabom]] ] 146 [[[link callable_traits.reference.ref_qualified_class_of [^qualified_class_of]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 147 [[[link callable_traits.reference.ref_remove_member_const [^remove_member_const]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[noabom]] [[noabom]] ] 148 [[[link callable_traits.reference.ref_remove_member_cv [^remove_member_cv]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[noabom]] [[noabom]] ] 149 [[[link callable_traits.reference.ref_remove_member_reference [^remove_member_reference]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[noop]] [[noop]] ] 150 [[[link callable_traits.reference.ref_remove_member_volatile [^remove_member_volatile]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[noabom]] [[noabom]] ] 151 [[[link callable_traits.reference.ref_remove_noexcept [^remove_noexcept]]] [[c17]] [[c17]] [[c17]] [[noop]] [[noop]] [[noop]] [[noop]] ] 152 [[[link callable_traits.reference.ref_remove_transaction_safe [^remove_transaction_safe]]] [[gnutm]] [[gnutm]] [[gnutm]] [[noop]] [[noop]] [[noop]] [[noop]] ] 153 [[[link callable_traits.reference.ref_remove_varargs [^remove_varargs]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 154 [[[link callable_traits.reference.ref_return_type [^return_type]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 155] 156 157[table LLVM/Clang Support 158 [[feature] [Clang 7.0.1] [Clang 6.0.0] [Clang 5.0.1] [Clang 4.0.0] [Clang 3.8.0] [Clang 3.7.1] [Clang 3.6.2] [Clang 3.5.2]] 159 [[[link callable_traits.reference.ref_add_member_const [^add_member_const]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 160 [[[link callable_traits.reference.ref_add_member_cv [^add_member_cv]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 161 [[[link callable_traits.reference.ref_add_member_lvalue_reference [^add_member_lvalue_reference]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 162 [[[link callable_traits.reference.ref_add_member_rvalue_reference [^add_member_rvalue_reference]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 163 [[[link callable_traits.reference.ref_add_member_volatile [^add_member_volatile]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 164 [[[link callable_traits.reference.ref_add_noexcept [^add_noexcept]]] [[c11]] [[c17]] [[c17]] [[c17]] [[no]] [[no]] [[no]] [[no]] ] 165 [[[link callable_traits.reference.ref_add_transaction_safe [^add_transaction_safe]]] [[unk]] [[unk]] [[unk]] [[unk]] [[no]] [[no]] [[no]] [[no]] ] 166 [[[link callable_traits.reference.ref_add_varargs [^add_varargs]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 167 [[[link callable_traits.reference.ref_apply_member_pointer [^apply_member_pointer]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 168 [[[link callable_traits.reference.ref_apply_return [^apply_return]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 169 [[[link callable_traits.reference.ref_args [^args]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 170 [[[link callable_traits.reference.ref_class_of [^class_of]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 171 [[[link callable_traits.reference.ref_function_type [^function_type]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 172 [[[link callable_traits.reference.ref_has_member_qualifiers [^has_member_qualifiers]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 173 [[[link callable_traits.reference.ref_has_varargs [^has_varargs]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 174 [[[link callable_traits.reference.ref_has_void_return [^has_void_return]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 175 [[[link callable_traits.reference.ref_is_const_member [^is_const_member]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 176 [[[link callable_traits.reference.ref_is_cv_member [^is_cv_member]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 177 [[[link callable_traits.reference.ref_is_invocable [^is_invocable]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 178 [[[link callable_traits.reference.ref_is_lvalue_reference_member [^is_lvalue_reference_member]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 179 [[[link callable_traits.reference.ref_is_noexcept [^is_noexcept]]] [[c17]] [[c17]] [[c17]] [[c17]] [[falsy]] [[falsy]] [[falsy]] [[falsy]] ] 180 [[[link callable_traits.reference.ref_is_reference_member [^is_reference_member]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 181 [[[link callable_traits.reference.ref_is_rvalue_reference_member [^is_rvalue_reference_member]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 182 [[[link callable_traits.reference.ref_is_transaction_safe [^is_transaction_safe]]] [[unk]] [[unk]] [[unk]] [[unk]] [[falsy]] [[falsy]] [[falsy]] [[falsy]] ] 183 [[[link callable_traits.reference.ref_is_volatile_member [^is_volatile_member]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 184 [[[link callable_traits.reference.ref_qualified_class_of [^qualified_class_of]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 185 [[[link callable_traits.reference.ref_remove_member_const [^remove_member_const]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 186 [[[link callable_traits.reference.ref_remove_member_cv [^remove_member_cv]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 187 [[[link callable_traits.reference.ref_remove_member_reference [^remove_member_reference]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 188 [[[link callable_traits.reference.ref_remove_member_volatile [^remove_member_volatile]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 189 [[[link callable_traits.reference.ref_remove_noexcept [^remove_noexcept]]] [[c17]] [[c17]] [[c17]] [[c17]] [[noop]] [[noop]] [[noop]] [[noop]] ] 190 [[[link callable_traits.reference.ref_remove_transaction_safe [^remove_transaction_safe]]] [[unk]] [[unk]] [[unk]] [[unk]] [[noop]] [[noop]] [[noop]] [[noop]] ] 191 [[[link callable_traits.reference.ref_remove_varargs [^remove_varargs]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 192 [[[link callable_traits.reference.ref_return_type [^return_type]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 193] 194 195[table XCode/AppleClang Support 196 [[feature] [XCode 8] [XCode 7.3] [XCode 7.2] [XCode 7.1] [XCode 6.4]] 197 [[[link callable_traits.reference.ref_add_member_const [^add_member_const]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 198 [[[link callable_traits.reference.ref_add_member_cv [^add_member_cv]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 199 [[[link callable_traits.reference.ref_add_member_lvalue_reference [^add_member_lvalue_reference]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 200 [[[link callable_traits.reference.ref_add_member_rvalue_reference [^add_member_rvalue_reference]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 201 [[[link callable_traits.reference.ref_add_member_volatile [^add_member_volatile]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 202 [[[link callable_traits.reference.ref_add_noexcept [^add_noexcept]]] [[unk]] [[no]] [[no]] [[no]] [[no]] ] 203 [[[link callable_traits.reference.ref_add_transaction_safe [^add_transaction_safe]]] [[unk]] [[no]] [[no]] [[no]] [[no]] ] 204 [[[link callable_traits.reference.ref_add_varargs [^add_varargs]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 205 [[[link callable_traits.reference.ref_apply_member_pointer [^apply_member_pointer]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 206 [[[link callable_traits.reference.ref_apply_return [^apply_return]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 207 [[[link callable_traits.reference.ref_args [^args]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 208 [[[link callable_traits.reference.ref_class_of [^class_of]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 209 [[[link callable_traits.reference.ref_function_type [^function_type]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 210 [[[link callable_traits.reference.ref_has_member_qualifiers [^has_member_qualifiers]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 211 [[[link callable_traits.reference.ref_has_varargs [^has_varargs]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 212 [[[link callable_traits.reference.ref_has_void_return [^has_void_return]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 213 [[[link callable_traits.reference.ref_is_const_member [^is_const_member]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 214 [[[link callable_traits.reference.ref_is_cv_member [^is_cv_member]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 215 [[[link callable_traits.reference.ref_is_invocable [^is_invocable]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 216 [[[link callable_traits.reference.ref_is_lvalue_reference_member [^is_lvalue_reference_member]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 217 [[[link callable_traits.reference.ref_is_noexcept [^is_noexcept]]] [[unk]] [[falsy]] [[falsy]] [[falsy]] [[falsy]] ] 218 [[[link callable_traits.reference.ref_is_reference_member [^is_reference_member]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 219 [[[link callable_traits.reference.ref_is_rvalue_reference_member [^is_rvalue_reference_member]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 220 [[[link callable_traits.reference.ref_is_transaction_safe [^is_transaction_safe]]] [[unk]] [[falsy]] [[falsy]] [[falsy]] [[falsy]] ] 221 [[[link callable_traits.reference.ref_is_volatile_member [^is_volatile_member]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 222 [[[link callable_traits.reference.ref_qualified_class_of [^qualified_class_of]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 223 [[[link callable_traits.reference.ref_remove_member_const [^remove_member_const]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 224 [[[link callable_traits.reference.ref_remove_member_cv [^remove_member_cv]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 225 [[[link callable_traits.reference.ref_remove_member_reference [^remove_member_reference]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 226 [[[link callable_traits.reference.ref_remove_member_volatile [^remove_member_volatile]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 227 [[[link callable_traits.reference.ref_remove_noexcept [^remove_noexcept]]] [[unk]] [[noop]] [[noop]] [[noop]] [[noop]] ] 228 [[[link callable_traits.reference.ref_remove_transaction_safe [^remove_transaction_safe]]] [[unk]] [[noop]] [[noop]] [[noop]] [[noop]] ] 229 [[[link callable_traits.reference.ref_remove_varargs [^remove_varargs]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 230 [[[link callable_traits.reference.ref_return_type [^return_type]]] [[c11]] [[c11]] [[c11]] [[c11]] [[c11]] ] 231] 232 233[table Visual Studio Support 234 [[feature] [MSVC with Visual Studio 2017] [MSVC with Visual Studio 2015 (latest update)]] 235 [[[link callable_traits.reference.ref_add_member_const [^add_member_const]]] [[c11]] [[c11]] ] 236 [[[link callable_traits.reference.ref_add_member_cv [^add_member_cv]]] [[c11]] [[c11]] ] 237 [[[link callable_traits.reference.ref_add_member_lvalue_reference [^add_member_lvalue_reference]]] [[c11]] [[c11]] ] 238 [[[link callable_traits.reference.ref_add_member_rvalue_reference [^add_member_rvalue_reference]]] [[c11]] [[c11]] ] 239 [[[link callable_traits.reference.ref_add_member_volatile [^add_member_volatile]]] [[c11]] [[c11]] ] 240 [[[link callable_traits.reference.ref_add_noexcept [^add_noexcept]]] [[no]] [[no]] ] 241 [[[link callable_traits.reference.ref_add_transaction_safe [^add_transaction_safe]]] [[no]] [[no]] ] 242 [[[link callable_traits.reference.ref_add_varargs [^add_varargs]]] [[c11] (define BOOST_DISABLE_WIN32 to disable __cdecl on PMF varargs)] [[c11] (define BOOST_DISABLE_WIN32 to disable __cdecl on PMF varargs)] ] 243 [[[link callable_traits.reference.ref_apply_member_pointer [^apply_member_pointer]]] [[c11]] [[c11]] ] 244 [[[link callable_traits.reference.ref_apply_return [^apply_return]]] [[c11]] [[c11]] ] 245 [[[link callable_traits.reference.ref_args [^args]]] [[c11]] [[c11]] ] 246 [[[link callable_traits.reference.ref_class_of [^class_of]]] [[c11]] [[c11]] ] 247 [[[link callable_traits.reference.ref_function_type [^function_type]]] [[c11]] [[c11]] ] 248 [[[link callable_traits.reference.ref_has_member_qualifiers [^has_member_qualifiers]]] [[c11]] [[c11]] ] 249 [[[link callable_traits.reference.ref_has_varargs [^has_varargs]]] [[c11] (define BOOST_DISABLE_WIN32 to disable __cdecl on PMF varargs)] [[c11] (define BOOST_DISABLE_WIN32 to disable __cdecl on PMF varargs)] ] 250 [[[link callable_traits.reference.ref_has_void_return [^has_void_return]]] [[c11]] [[c11]] ] 251 [[[link callable_traits.reference.ref_is_const_member [^is_const_member]]] [[c11]] [[c11]] ] 252 [[[link callable_traits.reference.ref_is_cv_member [^is_cv_member]]] [[c11]] [[c11]] ] 253 [[[link callable_traits.reference.ref_is_invocable [^is_invocable]]] [[c11]] [[role gold c++11] (always false for functions that are simultaneously ref and cv-qualified due to compiler bug)] ] 254 [[[link callable_traits.reference.ref_is_lvalue_reference_member [^is_lvalue_reference_member]]] [[c11]] [[c11]] ] 255 [[[link callable_traits.reference.ref_is_noexcept [^is_noexcept]]] [[falsy]] [[falsy]] ] 256 [[[link callable_traits.reference.ref_is_reference_member [^is_reference_member]]] [[c11]] [[c11]] ] 257 [[[link callable_traits.reference.ref_is_rvalue_reference_member [^is_rvalue_reference_member]]] [[c11]] [[c11]] ] 258 [[[link callable_traits.reference.ref_is_transaction_safe [^is_transaction_safe]]] [[falsy]] [[falsy]] ] 259 [[[link callable_traits.reference.ref_is_volatile_member [^is_volatile_member]]] [[c11]] [[c11]] ] 260 [[[link callable_traits.reference.ref_qualified_class_of [^qualified_class_of]]] [[c11]][[c11]] ] 261 [[[link callable_traits.reference.ref_remove_member_const [^remove_member_const]]] [[c11]] [[c11]] ] 262 [[[link callable_traits.reference.ref_remove_member_cv [^remove_member_cv]]] [[c11]] [[c11]] ] 263 [[[link callable_traits.reference.ref_remove_member_reference [^remove_member_reference]]] [[c11]] [[c11]] ] 264 [[[link callable_traits.reference.ref_remove_member_volatile [^remove_member_volatile]]] [[c11]] [[c11]] ] 265 [[[link callable_traits.reference.ref_remove_noexcept [^remove_noexcept]]] [[noop]] [[noop]] ] 266 [[[link callable_traits.reference.ref_remove_transaction_safe [^remove_transaction_safe]]] [[noop]] [[noop]] ] 267 [[[link callable_traits.reference.ref_remove_varargs [^remove_varargs]]] [[c11] (define BOOST_DISABLE_WIN32 to disable __cdecl on PMF varargs)] [[c11] (define BOOST_DISABLE_WIN32 to disable __cdecl on PMF varargs)] ] 268 [[[link callable_traits.reference.ref_return_type [^return_type]]] [[c11]] [[c11]] ] 269] 270 271[endsect][/section:compatibility] 272 273[endsect][/section:introduction] 274 275 276[section:reference Reference Documentation] 277 278This reference will be most beneficial to readers familiar with the following C++ topics: 279 280* [@http://en.cppreference.com/w/cpp/language/partial_specialization template specializations] 281* [@http://en.cppreference.com/w/cpp/language/sfinae SFINAE] 282* [invoke] rules 283* function types 284* [@http://en.cppreference.com/w/cpp/language/pointer#Pointers_to_functions function pointers] 285* [@http://stackoverflow.com/questions/480248/function-references function references] 286* [@http://en.cppreference.com/w/cpp/language/pointer#Pointers_to_member_functions pointers to member functions] (a.k.a. PMFs) 287* [@http://en.cppreference.com/w/cpp/language/pointer#Pointers_to_data_members pointers to data members] (a.k.a. PMDs) 288* [@http://en.cppreference.com/w/cpp/language/operators#Function_call_operator the function call operator, [^operator()]] 289* [@https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers universal references] and [@http://stackoverflow.com/questions/13725747/concise-explanation-of-reference-collapsing-rules-requested-1-a-a-2 reference collapsing rules] 290* [@http://en.cppreference.com/w/cpp/language/member_functions#const-.2C_volatile-.2C_and_ref-qualified_member_functions cv-qualified and ref-qualified member functions] 291* [abominable_paper] 292* [@http://en.cppreference.com/w/c/language/variadic C-style variadics], a.k.a. varargs 293 294[import ../../../boost/callable_traits/add_member_const.hpp] 295[add_member_const_hpp] 296 297[import ../../../boost/callable_traits/add_member_cv.hpp] 298[add_member_cv_hpp] 299 300[import ../../../boost/callable_traits/add_member_lvalue_reference.hpp] 301[add_member_lvalue_reference_hpp] 302 303[import ../../../boost/callable_traits/add_member_rvalue_reference.hpp] 304[add_member_rvalue_reference_hpp] 305 306[import ../../../boost/callable_traits/add_member_volatile.hpp] 307[add_member_volatile_hpp] 308 309[import ../../../boost/callable_traits/add_noexcept.hpp] 310[add_noexcept_hpp] 311 312[import ../../../boost/callable_traits/add_transaction_safe.hpp] 313[add_transaction_safe_hpp] 314 315[import ../../../boost/callable_traits/add_varargs.hpp] 316[add_varargs_hpp] 317 318[import ../../../boost/callable_traits/apply_member_pointer.hpp] 319[apply_member_pointer_hpp] 320 321[import ../../../boost/callable_traits/apply_return.hpp] 322[apply_return_hpp] 323 324[import ../../../boost/callable_traits/args.hpp] 325[args_hpp] 326 327[import ../../../boost/callable_traits/class_of.hpp] 328[class_of_hpp] 329 330[import ../../../boost/callable_traits/function_type.hpp] 331[function_type_hpp] 332 333[import ../../../boost/callable_traits/has_member_qualifiers.hpp] 334[has_member_qualifiers_hpp] 335 336[import ../../../boost/callable_traits/has_varargs.hpp] 337[has_varargs_hpp] 338 339[import ../../../boost/callable_traits/has_void_return.hpp] 340[has_void_return_hpp] 341 342[import ../../../boost/callable_traits/is_const_member.hpp] 343[is_const_member_hpp] 344 345[import ../../../boost/callable_traits/is_cv_member.hpp] 346[is_cv_member_hpp] 347 348[import ../../../boost/callable_traits/is_invocable.hpp] 349[is_invocable_hpp] 350 351[import ../../../boost/callable_traits/is_lvalue_reference_member.hpp] 352[is_lvalue_reference_member_hpp] 353 354[import ../../../boost/callable_traits/is_reference_member.hpp] 355[is_reference_member_hpp] 356 357[import ../../../boost/callable_traits/is_rvalue_reference_member.hpp] 358[is_rvalue_reference_member_hpp] 359 360[import ../../../boost/callable_traits/is_noexcept.hpp] 361[is_noexcept_hpp] 362 363[import ../../../boost/callable_traits/is_transaction_safe.hpp] 364[is_transaction_safe_hpp] 365 366[import ../../../boost/callable_traits/is_volatile_member.hpp] 367[is_volatile_member_hpp] 368 369[import ../../../boost/callable_traits/qualified_class_of.hpp] 370[qualified_class_of_hpp] 371 372[import ../../../boost/callable_traits/remove_member_const.hpp] 373[remove_member_const_hpp] 374 375[import ../../../boost/callable_traits/remove_member_cv.hpp] 376[remove_member_cv_hpp] 377 378[import ../../../boost/callable_traits/remove_member_reference.hpp] 379[remove_member_reference_hpp] 380 381[import ../../../boost/callable_traits/remove_member_volatile.hpp] 382[remove_member_volatile_hpp] 383 384[import ../../../boost/callable_traits/remove_noexcept.hpp] 385[remove_noexcept_hpp] 386 387[import ../../../boost/callable_traits/remove_transaction_safe.hpp] 388[remove_transaction_safe_hpp] 389 390[import ../../../boost/callable_traits/remove_varargs.hpp] 391[remove_varargs_hpp] 392 393[import ../../../boost/callable_traits/return_type.hpp] 394[return_type_hpp] 395 396[endsect][/section:reference] 397 398[/*********************************************************************] 399[/***************************** F A Q *********************************] 400[/*********************************************************************] 401 402[section:faq FAQ] 403 404[heading:reasons Why should I use [libname]?] 405 406If you are not writing generic code, you should not use [libname]. 407 408If you ['are] writing generic code, take a moment to skim your header files, and see if you can find code that looks like this: 409 410 template<class Return, class First, class Second> 411 class foo<Return(First, Second)> { 412 // ^^^^^^^^^^^^^^^^^^^^^ 413 }; 414 415Or maybe something like this: 416 417 template<class Return, class ...Args> 418 class foo<Return(*)(Args...)> { 419 // ^^^^^^^^^^^^^^^^^^ 420 }; 421 422Or, if you are *really* unlucky, something like this: 423 424 template<class Return, class T, class ...Args> 425 class foo<Return(T::*)(Args..., ...) const volatile & noexcept> { 426 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 427 }; 428 429With [libname], you can get rid of all of these template specializations (unless you deal with platform-specific calling conventions, for now). Even if you are only specializing a simple function type like `Return(Args...)`, [libname] might be useful to you. You may find that [libname] can help make your code more readable, more maintainable, more generic, and less error-prone. 430 431[libname] is well-tested on many platforms. [libname] correctly handles many corner cases that are often overlooked. The need for a proper library solution grows as more features are added to C++. 432 433[heading Boost is a massive dependency. Do I really need it?] 434 435Nope! [libname] doesn't have any dependencies, so all you need are the [libname] headers. 436 437[heading Why use reference collapsing rules when adding member function ref-qualifiers?] 438 439Although arbitrary, the reference collapsing rules are well-defined and already known to many template metaprogrammers. Anything else would be a burden to memorize. This also parallels the metafunctions provided in `<type_traits>`. 440 441[heading Many features in this library cause a "substitution failure" when the template constraints are violated. Does this mean that I can violate the constraints in a SFINAE context, as long as there is another legal substitute?] 442 443Yes. The SFINAE-ability of violated constraints has been tested extensively on supported compilers. Achieving this required some messy code in the public header files. 444 445[heading What about calling conventions?] 446 447I originally implemented features for these. However, these features necessitated many, many more platform-specific test cases. The code is still designed to accommodate such features, so I would consider adding them in the future if there is sufficient interest. 448 449[endsect] 450 451[section:building Building the test suite] 452 453This section contains the instructions for building and running the test cases and documentatation examples that are packaged with [libname]. 454 455[note Some test cases that use language features that do not work on some supported compilers. These conflicts are "resolved" by replacing `int main(){}` with the actual test via conditional compilation.] 456 457[heading Dependencies] 458 459Even though the [libname] headers do not rely on external dependencies, you'll need to install [@https://cmake.org/ CMake] version 3.5 or higher to run the full test suite. The build instructions assume that both CMake and Git are available from your environment PATH. Boost.Build is also supported. 460 461[heading Linux/OSX - clone and run test suite] 462 463Open a shell and enter the following commands: 464 465``` 466git clone http://github.com/boostorg/callable_traits 467cd callable_traits 468mkdir build 469cd build 470cmake .. -DCMAKE_CXX_COMPILER=/path/to/compiler 471make check 472``` 473 474[heading Windows - clone and run test suite] 475 476[note Cygwin and MSYS users should refer to the Linux section (you know who you are).] 477 478Fire up `cmd.exe` and enter the following commands: 479 480``` 481git clone http://github.com/boostorg/callable_traits 482cd callable_traits 483mkdir build 484cd build 485cmake .. 486path\to\msbuild.exe check.vcxproj /t:build /p:Configuration=Debug /p:Platform=Win32 /v:n /nologo 487``` 488 489To build with Clang/C2 instead of MSVC, append `-TLLVM-vs2014` (or similar supported flag) to the CMake arguments. This will only work if you have Clang/C2 installed. 490 491[endsect][/section:building] 492 493 494[/*********************************************************************] 495[/************************* C O N T A C T *****************************] 496[/*********************************************************************] 497 498[section:contact Contact] 499 500[libname] is authored and maintained by Barrett Adair. 501 502Comments, feedback, bug reports, and questions are appreciated, which can be submitted in the following ways: 503 504* Open a new issue [@https://github.com/boostorg/callable_traits/issues/new] on GitHub 505* Send an email to barrettellisadair 506* ...at gmail.com 507 508[endsect][/section:contact] 509 510[section:acknowledgements Acknowledgements] 511 512Credit to Tobias Schwinger for authoring the influential [function_types_link]. 513 514Thanks to the following people for their reviews and feedback: 515 516* Bruno Dutra 517* Edward Diener 518* Emil Dotchevski 519* Gavin Lambert 520* Jason Rice 521* John Fletcher 522* Klemens Morgenstern 523* Niall Douglas 524* Paul Fultz II 525* Peter Dimov 526* Tim Song 527* Zach Laine 528 529Special thanks to... 530 531* Louis Dionne, for the significant time and effort spent as the Boost review manager, and for introducing me to the exciting world of Boost development. 532* The Harding University Computer Science Department, for the all of the challenging instruction, inspiration, and mentorship (especially to Dr. Dana Steil, for teaching me the joy of C++) 533* My family, for the support and encouragement during the development of this library, and for so much more. 534 535[endsect][/section:acknowledgements]