Boost C++ 库

...世界上最受推崇和设计最精良的 C++ 库项目之一。 Herb SutterAndrei Alexandrescu, C++ 编码标准

Next

CallableTraits

Barrett Adair

根据 Boost 软件许可协议 1.0 版分发。(请参阅随附文件 LICENSE.md 或访问 https://boost.ac.cn/LICENSE_1_0.txt)


目录

概述
动机
关于 Boost.FunctionTypes
兼容性
参考文档
add_member_const
add_member_cv
add_member_lvalue_reference
add_member_rvalue_reference
add_member_volatile
add_noexcept
add_transaction_safe
add_varargs
apply_member_pointer
apply_return
args
class_of
function_type
has_member_qualifiers
has_varargs
has_void_return
is_const_member
is_cv_member
is_invocable
is_lvalue_reference_member
is_reference_member
is_rvalue_reference_member
is_noexcept
is_transaction_safe
is_volatile_member
qualified_class_of
remove_member_const
remove_member_cv
remove_member_reference
remove_member_volatile
remove_noexcept
remove_transaction_safe
remove_varargs
return_type
FAQ
构建测试套件
联系方式
鸣谢

Boost.CallableTraits 是一个 C++11 的仅头文件库,用于检查、合成和分解可调用类型。Boost.CallableTraits 旨在成为 C++17 提案 p0172 的最后一段中提到的 “用于函数类型的完整类型操作工具”,并消除了对不同函数签名进行模板特化的需求。如果可用,也支持 C++17 noexcept 和事务内存 TS。

#include <type_traits>
#include <tuple>
#include <boost/callable_traits.hpp>

namespace ct = boost::callable_traits;

// This function template helps keep our example code neat
template<typename A, typename B>
void assert_same(){ static_assert(std::is_same<A, B>::value, ""); }

// foo is a function object
struct foo {
    void operator()(int, char, float) const {}
};

int main() {

    // Use args_t to retrieve a parameter list as a std::tuple:
    assert_same<
        ct::args_t<foo>,
        std::tuple<int, char, float>
    >();

    // has_void_return lets us perform a quick check for a void return type
    static_assert(ct::has_void_return<foo>::value, "");

    // Detect C-style variadics (ellipses) in a signature (e.g. printf)
    static_assert(!ct::has_varargs<foo>::value, "");

    // pmf is a pointer-to-member function: void (foo::*)(int, char, float) const
    using pmf = decltype(&foo::operator());

    // remove_member_const_t lets you remove the const member qualifier
    assert_same<
        ct::remove_member_const_t<pmf>,
        void (foo::*)(int, char, float) /*no const!*/
    >();

    // Conversely, add_member_const_t adds a const member qualifier
    assert_same<
        pmf,
        ct::add_member_const_t<void (foo::*)(int, char, float)>
    >();

    // is_const_member_v checks for the presence of member const
    static_assert(ct::is_const_member<pmf>::value, "");
}

不要尝试编写辅助代码来检测 PMF/PMD 并对其进行分派 -- 这绝对是一场噩梦。PMF 类型是核心语言中最糟糕的类型。

-- Stephan T. Lavavej, CppCon 2015, "functional: What's New, And Proper Usage"

考虑一下下面的代码,它定义了 48 个模板特化,这些特化对于在纯 C++17 中为每个有效的函数类型进行特化是必要的

template<typename T> struct foo;

template<class Return, class... Args> struct foo<Return(Args...)> {};
template<class Return, class... Args> struct foo<Return(Args...) &> {};
template<class Return, class... Args> struct foo<Return(Args...) &&> {};
template<class Return, class... Args> struct foo<Return(Args...) const> {};
template<class Return, class... Args> struct foo<Return(Args...) const &> {};
template<class Return, class... Args> struct foo<Return(Args...) const &&> {};
template<class Return, class... Args> struct foo<Return(Args...) volatile> {};
template<class Return, class... Args> struct foo<Return(Args...) volatile &> {};
template<class Return, class... Args> struct foo<Return(Args...) volatile &&> {};
template<class Return, class... Args> struct foo<Return(Args...) const volatile> {};
template<class Return, class... Args> struct foo<Return(Args...) const volatile &> {};
template<class Return, class... Args> struct foo<Return(Args...) const volatile &&> {};
template<class Return, class... Args> struct foo<Return(Args..., ...)> {};
template<class Return, class... Args> struct foo<Return(Args..., ...) &> {};
template<class Return, class... Args> struct foo<Return(Args..., ...) &&> {};
template<class Return, class... Args> struct foo<Return(Args..., ...) const> {};
template<class Return, class... Args> struct foo<Return(Args..., ...) const &> {};
template<class Return, class... Args> struct foo<Return(Args..., ...) const &&> {};
template<class Return, class... Args> struct foo<Return(Args..., ...) volatile> {};
template<class Return, class... Args> struct foo<Return(Args..., ...) volatile &> {};
template<class Return, class... Args> struct foo<Return(Args..., ...) volatile &&> {};
template<class Return, class... Args> struct foo<Return(Args..., ...) const volatile> {};
template<class Return, class... Args> struct foo<Return(Args..., ...) const volatile &> {};
template<class Return, class... Args> struct foo<Return(Args..., ...) const volatile &&> {};
template<class Return, class... Args> struct foo<Return(Args...) noexcept> {};
template<class Return, class... Args> struct foo<Return(Args...) & noexcept> {};
template<class Return, class... Args> struct foo<Return(Args...) && noexcept> {};
template<class Return, class... Args> struct foo<Return(Args...) const noexcept> {};
template<class Return, class... Args> struct foo<Return(Args...) const & noexcept> {};
template<class Return, class... Args> struct foo<Return(Args...) const && noexcept> {};
template<class Return, class... Args> struct foo<Return(Args...) volatile noexcept> {};
template<class Return, class... Args> struct foo<Return(Args...) volatile & noexcept> {};
template<class Return, class... Args> struct foo<Return(Args...) volatile && noexcept> {};
template<class Return, class... Args> struct foo<Return(Args...) const volatile noexcept> {};
template<class Return, class... Args> struct foo<Return(Args...) const volatile & noexcept> {};
template<class Return, class... Args> struct foo<Return(Args...) const volatile && noexcept> {};
template<class Return, class... Args> struct foo<Return(Args..., ...) noexcept> {};
template<class Return, class... Args> struct foo<Return(Args..., ...) & noexcept> {};
template<class Return, class... Args> struct foo<Return(Args..., ...) && noexcept> {};
template<class Return, class... Args> struct foo<Return(Args..., ...) const noexcept> {};
template<class Return, class... Args> struct foo<Return(Args..., ...) const & noexcept> {};
template<class Return, class... Args> struct foo<Return(Args..., ...) const && noexcept> {};
template<class Return, class... Args> struct foo<Return(Args..., ...) volatile noexcept> {};
template<class Return, class... Args> struct foo<Return(Args..., ...) volatile & noexcept> {};
template<class Return, class... Args> struct foo<Return(Args..., ...) volatile && noexcept> {};
template<class Return, class... Args> struct foo<Return(Args..., ...) const volatile noexcept> {};
template<class Return, class... Args> struct foo<Return(Args..., ...) const volatile & noexcept> {};
template<class Return, class... Args> struct foo<Return(Args..., ...) const volatile && noexcept> {};

对于成员函数指针、函数指针、函数引用、函数对象和 transaction_safe,情况变得更加复杂。

诚然,在日常应用程序代码库中,这种晦涩的特化的用例几乎不存在。即使在库代码中,这些也极其罕见。然而,有一些元编程场景只能通过这种模板“垃圾信息”来解决。编写、测试和维护此类代码既乏味又昂贵。

Boost.CallableTraits 为这个问题提供了一个最终且决定性的库级解决方案,并完全消除了对这些特化的需求(平台特定的调用约定除外)。

Boost.CallableTraits 中的功能在很大程度上与 Boost.FunctionTypes 重叠。以下是您可能更喜欢 Boost.CallableTraits 的一些原因

  1. Boost.FunctionTypesBoost.MPL 序列紧密耦合,而 Boost.CallableTraits 除了标准库之外没有其他依赖项。
  2. Boost.CallableTraits 目标是 C++11 及更高版本
    1. Boost.CallableTraits 将函数对象/lambda 表达式视为一等公民。
    2. Boost.CallableTraits 支持左值/右值引用成员限定符。
    3. Boost.CallableTraits 支持 noexcepttransaction_safe
  3. Boost.FunctionTypes 不尝试将所有可调用类型分解为统一的、INVOKE-感知接口。
  4. Boost.FunctionTypes 严重依赖“标签”类型,而 Boost.CallableTraits 遵循 <type_traits> 的风格。在 Boost.FunctionTypes 中支持 C++11 及更高版本将需要大量这些标签的扩散。

例如,以下是如何在 Boost.FunctionTypes 库中从成员函数指针类型中删除成员 const 的方法

#include <type_traits>
#include <boost/function_types/components.hpp>
#include <boost/function_types/member_function_pointer.hpp>

struct foo {
    void bar() const {}
};

using const_removed = typename boost::function_types::member_function_pointer<
    typename boost::function_types::components<decltype(&foo::bar)>::types,
    boost::function_types::non_const>::type;

static_assert(std::is_same<const_removed, void(foo::*)()>::value, "");

int main(){}

Boost.CallableTraits 使这更容易

#include <type_traits>
#include <boost/callable_traits/remove_member_const.hpp>

struct foo {
        void bar() const {}
};

using const_removed = boost::callable_traits::remove_member_const_t<decltype(&foo::bar)>;

static_assert(std::is_same<const_removed, void(foo::*)()>::value, "");

int main(){}

Boost.FunctionTypes 库包含一个出色的 示例,用于生成类型擦除接口(实现 在此)。此示例已使用 Boost.CallableTraits 重新实现,以产生 稍微更直观的接口

Boost.FunctionTypes 是一个优秀的库,但其接口仍有改进空间。

Boost.CallableTraits 在 GCC 4.7.4+、Clang 3.5.2+、XCode 6.4+ 和 Visual Studio 2015+ 上受支持。Intel C++ 编译器未正式支持,尽管适用于 Linux 的 2017 版本确实通过了一些测试用例。

表 1. GCC 支持

功能

GCC 7.3.0 及更高版本

GCC 6.3.0

GCC 5.4.0

GCC 4.9.2

GCC 4.8.2

GCC 4.7.4

add_member_const

c++11

c++11

c++11

c++11

c++11 (无 abominables)

c++11 (无 abominables)

add_member_cv

c++11

c++11

c++11

c++11

c++11 (无 abominables)

c++11 (无 abominables)

add_member_lvalue_reference

c++11

c++11

c++11

c++11

static_assert 在实例化时失败

static_assert 在实例化时失败

add_member_rvalue_reference

c++11

c++11

c++11

c++11

static_assert 在实例化时失败

static_assert 在实例化时失败

add_member_volatile

c++11

c++11

c++11

c++11

c++11 (无 abominables)

c++11 (无 abominables)

add_noexcept

c++17

c++17

static_assert 在实例化时失败

static_assert 在实例化时失败

static_assert 在实例化时失败

static_assert 在实例化时失败

add_transaction_safe

c++17 (需要 -fgnu-tm)

c++17 (需要 -fgnu-tm)

static_assert 在实例化时失败

static_assert 在实例化时失败

static_assert 在实例化时失败

static_assert 在实例化时失败

add_varargs

c++11

c++11

c++11

c++11

c++11

c++11

apply_member_pointer

c++11

c++11

c++11

c++11

c++11

c++11

apply_return

c++11

c++11

c++11

c++11

c++11

c++11

args

c++11

c++11

c++11

c++11

c++11

c++11

class_of

c++11

c++11

c++11

c++11

c++11

c++11

function_type

c++11

c++11

c++11

c++11

c++11

c++11

has_member_qualifiers

c++11

c++11

c++11

c++11

c++11 (无 abominables)

c++11 (无 abominables)

has_varargs

c++11

c++11

c++11

c++11

c++11

c++11

has_void_return

c++11

c++11

c++11

c++11

c++11

c++11

is_const_member

c++11

c++11

c++11

c++11

c++11 (无 abominables)

c++11 (无 abominables)

is_cv_member

c++11

c++11

c++11

c++11

c++11 (无 abominables)

c++11 (无 abominables)

is_invocable

c++11

c++11

c++11

c++11

未知

未知

is_lvalue_reference_member

c++11

c++11

c++11

c++11

c++11 (始终为 false)

c++11 (始终为 false)

is_noexcept

c++17

c++17

c++11 (始终为 false)

c++11 (始终为 false)

c++11 (始终为 false)

c++11 (始终为 false)

is_reference_member

c++11

c++11

c++11

c++11

c++11 (始终为 false)

c++11 (始终为 false)

is_rvalue_reference_member

c++11

c++11

c++11

c++11

c++11 (始终为 false)

c++11 (始终为 false)

is_transaction_safe

c++17 (需要 -fgnu-tm)

c++17 (需要 -fgnu-tm)

c++11 (始终为 false)

c++11 (始终为 false)

c++11 (始终为 false)

c++11 (始终为 false)

is_volatile_member

c++11

c++11

c++11

c++11

c++11 (无 abominables)

c++11 (无 abominables)

qualified_class_of

c++11

c++11

c++11

c++11

c++11

c++11

remove_member_const

c++11

c++11

c++11

c++11

c++11 (无 abominables)

c++11 (无 abominables)

remove_member_cv

c++11

c++11

c++11

c++11

c++11 (无 abominables)

c++11 (无 abominables)

remove_member_reference

c++11

c++11

c++11

c++11

c++11 (无效果)

c++11 (无效果)

remove_member_volatile

c++11

c++11

c++11

c++11

c++11 (无 abominables)

c++11 (无 abominables)

remove_noexcept

c++17

c++17

c++11 (无效果)

c++11 (无效果)

c++11 (无效果)

c++11 (无效果)

remove_transaction_safe

c++17 (需要 -fgnu-tm)

c++17 (需要 -fgnu-tm)

c++11 (无效果)

c++11 (无效果)

c++11 (无效果)

c++11 (无效果)

remove_varargs

c++11

c++11

c++11

c++11

c++11

c++11

return_type

c++11

c++11

c++11

c++11

c++11

c++11


表 2. LLVM/Clang 支持

功能

Clang 4.0.0 及更高版本

Clang 3.8.0

Clang 3.7.1

Clang 3.6.2

Clang 3.5.2

add_member_const

c++11

c++11

c++11

c++11

c++11

add_member_cv

c++11

c++11

c++11

c++11

c++11

add_member_lvalue_reference

c++11

c++11

c++11

c++11

c++11

add_member_rvalue_reference

c++11

c++11

c++11

c++11

c++11

add_member_volatile

c++11

c++11

c++11

c++11

c++11

add_noexcept

c++17

static_assert 在实例化时失败

static_assert 在实例化时失败

static_assert 在实例化时失败

static_assert 在实例化时失败

add_transaction_safe

static_assert 在实例化时失败

static_assert 在实例化时失败

static_assert 在实例化时失败

static_assert 在实例化时失败

static_assert 在实例化时失败

add_varargs

c++11

c++11

c++11

c++11

c++11

apply_member_pointer

c++11

c++11

c++11

c++11

c++11

apply_return

c++11

c++11

c++11

c++11

c++11

args

c++11

c++11

c++11

c++11

c++11

class_of

c++11

c++11

c++11

c++11

c++11

function_type

c++11

c++11

c++11

c++11

c++11

has_member_qualifiers

c++11

c++11

c++11

c++11

c++11

has_varargs

c++11

c++11

c++11

c++11

c++11

has_void_return

c++11

c++11

c++11

c++11

c++11

is_const_member

c++11

c++11

c++11

c++11

c++11

is_cv_member

c++11

c++11

c++11

c++11

c++11

is_invocable

c++11

c++11

c++11

c++11

c++11

is_lvalue_reference_member

c++11

c++11

c++11

c++11

c++11

is_noexcept

c++17

c++11 (始终为 false)

c++11 (始终为 false)

c++11 (始终为 false)

c++11 (始终为 false)

is_reference_member

c++11

c++11

c++11

c++11

c++11

is_rvalue_reference_member

c++11

c++11

c++11

c++11

c++11

is_transaction_safe

c++11 (始终为 false)

c++11 (始终为 false)

c++11 (始终为 false)

c++11 (始终为 false)

c++11 (始终为 false)

is_volatile_member

c++11

c++11

c++11

c++11

c++11

qualified_class_of

c++11

c++11

c++11

c++11

c++11

remove_member_const

c++11

c++11

c++11

c++11

c++11

remove_member_cv

c++11

c++11

c++11

c++11

c++11

remove_member_reference

c++11

c++11

c++11

c++11

c++11

remove_member_volatile

c++11

c++11

c++11

c++11

c++11

remove_noexcept

c++17

c++11 (无效果)

c++11 (无效果)

c++11 (无效果)

c++11 (无效果)

remove_transaction_safe

c++11 (无效果)

c++11 (无效果)

c++11 (无效果)

c++11 (无效果)

c++11 (无效果)

remove_varargs

c++11

c++11

c++11

c++11

c++11

return_type

c++11

c++11

c++11

c++11

c++11


表 3. XCode/AppleClang 支持

功能

XCode 8 及更高版本

XCode 7.3

XCode 7.2

XCode 7.1

XCode 6.4

add_member_const

c++11

c++11

c++11

c++11

c++11

add_member_cv

c++11

c++11

c++11

c++11

c++11

add_member_lvalue_reference

c++11

c++11

c++11

c++11

c++11

add_member_rvalue_reference

c++11

c++11

c++11

c++11

c++11

add_member_volatile

c++11

c++11

c++11

c++11

c++11

add_noexcept

未知

static_assert 在实例化时失败

static_assert 在实例化时失败

static_assert 在实例化时失败

static_assert 在实例化时失败

add_transaction_safe

未知

static_assert 在实例化时失败

static_assert 在实例化时失败

static_assert 在实例化时失败

static_assert 在实例化时失败

add_varargs

c++11

c++11

c++11

c++11

c++11

apply_member_pointer

c++11

c++11

c++11

c++11

c++11

apply_return

c++11

c++11

c++11

c++11

c++11

args

c++11

c++11

c++11

c++11

c++11

class_of

c++11

c++11

c++11

c++11

c++11

function_type

c++11

c++11

c++11

c++11

c++11

has_member_qualifiers

c++11

c++11

c++11

c++11

c++11

has_varargs

c++11

c++11

c++11

c++11

c++11

has_void_return

c++11

c++11

c++11

c++11

c++11

is_const_member

c++11

c++11

c++11

c++11

c++11

is_cv_member

c++11

c++11

c++11

c++11

c++11

is_invocable

c++11

c++11

c++11

c++11

c++11

is_lvalue_reference_member

c++11

c++11

c++11

c++11

c++11

is_noexcept

未知

c++11 (始终为 false)

c++11 (始终为 false)

c++11 (始终为 false)

c++11 (始终为 false)

is_reference_member

c++11

c++11

c++11

c++11

c++11

is_rvalue_reference_member

c++11

c++11

c++11

c++11

c++11

is_transaction_safe

未知

c++11 (始终为 false)

c++11 (始终为 false)

c++11 (始终为 false)

c++11 (始终为 false)

is_volatile_member

c++11

c++11

c++11

c++11

c++11

qualified_class_of

c++11

c++11

c++11

c++11

c++11

remove_member_const

c++11

c++11

c++11

c++11

c++11

remove_member_cv

c++11

c++11

c++11

c++11

c++11

remove_member_reference

c++11

c++11

c++11

c++11

c++11

remove_member_volatile

c++11

c++11

c++11

c++11

c++11

remove_noexcept

未知

c++11 (无效果)

c++11 (无效果)

c++11 (无效果)

c++11 (无效果)

remove_transaction_safe

未知

c++11 (无效果)

c++11 (无效果)

c++11 (无效果)

c++11 (无效果)

remove_varargs

c++11

c++11

c++11

c++11

c++11

return_type

c++11

c++11

c++11

c++11

c++11


表 4. Visual Studio 支持

功能

MSVC with Visual Studio 2017

MSVC with Visual Studio 2015 (最新更新)

add_member_const

c++11

c++11

add_member_cv

c++11

c++11

add_member_lvalue_reference

c++11

c++11

add_member_rvalue_reference

c++11

c++11

add_member_volatile

c++11

c++11

add_noexcept

static_assert 在实例化时失败

static_assert 在实例化时失败

add_transaction_safe

static_assert 在实例化时失败

static_assert 在实例化时失败

add_varargs

c++11 (定义 BOOST_DISABLE_WIN32 以禁用 PMF varargs 上的 __cdecl)

c++11 (定义 BOOST_DISABLE_WIN32 以禁用 PMF varargs 上的 __cdecl)

apply_member_pointer

c++11

c++11

apply_return

c++11

c++11

args

c++11

c++11

class_of

c++11

c++11

function_type

c++11

c++11

has_member_qualifiers

c++11

c++11

has_varargs

c++11 (定义 BOOST_DISABLE_WIN32 以禁用 PMF varargs 上的 __cdecl)

c++11 (定义 BOOST_DISABLE_WIN32 以禁用 PMF varargs 上的 __cdecl)

has_void_return

c++11

c++11

is_const_member

c++11

c++11

is_cv_member

c++11

c++11

is_invocable

c++11

c++11 (对于同时具有 ref 和 cv 限定符的函数,始终为 false,原因是编译器错误)

is_lvalue_reference_member

c++11

c++11

is_noexcept

c++11 (始终为 false)

c++11 (始终为 false)

is_reference_member

c++11

c++11

is_rvalue_reference_member

c++11

c++11

is_transaction_safe

c++11 (始终为 false)

c++11 (始终为 false)

is_volatile_member

c++11

c++11

qualified_class_of

c++11

c++11

remove_member_const

c++11

c++11

remove_member_cv

c++11

c++11

remove_member_reference

c++11

c++11

remove_member_volatile

c++11

c++11

remove_noexcept

c++11 (无效果)

c++11 (无效果)

remove_transaction_safe

c++11 (无效果)

c++11 (无效果)

remove_varargs

c++11 (定义 BOOST_DISABLE_WIN32 以禁用 PMF varargs 上的 __cdecl)

c++11 (定义 BOOST_DISABLE_WIN32 以禁用 PMF varargs 上的 __cdecl)

return_type

c++11

c++11



Next