c++ - 我们可以使用检测成语来检查类是否具有具有特定签名的成员函数吗?

标签 c++ templates c++14 sfinae typetraits

给定 detection idiom 的(简化)实现

namespace type_traits
{
    template<typename... Ts>
    using void_t = void;

    namespace detail
    {
        template<typename, template<typename...> class, typename...>
        struct is_detected : std::false_type {};

        template<template<class...> class Operation, typename... Arguments>
        struct is_detected<void_t<Operation<Arguments...>>, Operation, Arguments...> : std::true_type {};
    }

    template<template<class...> class Operation, typename... Arguments>
    using is_detected = detail::is_detected<void_t<>, Operation, Arguments...>;

    template<template<class...> class Operation, typename... Arguments>
    constexpr bool is_detected_v = detail::is_detected<void_t<>, Operation, Arguments...>::value;
}

我们可以轻松地检查类 foo 是否包含成员函数 bar

struct  foo {
    int const& bar(int&&) { return 0; }
};

template<class T>
using bar_t = decltype(std::declval<T>().bar(0));

int main()
{
    static_assert(type_traits::is_detected_v<bar_t, foo>, "not detected");
    return 0;
}

但是,如您所见,我们无法检测到foo::bar 的参数类型是int&&。检测成功,因为0可以传递给foo::bar。我知道有很多选项可以检查(成员)函数的精确 签名。但我想知道,是否可以修改此检测工具包以检测 foo::bar 的参数类型恰好是 int&&

[我创建了一个 live demo这个例子。]

最佳答案

在不改变你的 type_traits 的情况下,你可以这样做

template<typename T, T> struct helper {};

template<class T>
using bar_t = decltype(helper<const int& (T::*)(int&&), &T::bar>{});

Demo

关于c++ - 我们可以使用检测成语来检查类是否具有具有特定签名的成员函数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35843485/

相关文章:

c++ - #if 预处理器指令可以嵌套在 C++ 中吗?

c++ - VS2010 调试器在 watch 窗口中没有正确跟踪变量,VS2013 是否还有这个错误?

c++ - 在 C++ 中调用作为参数传递的同一模板函数的两个版本

c++ - 标准 C++14 委员会草案是否公开?

C++14 在方法定义中使用 auto 关键字

c++ - 当 std::fstream 都移动一个指针时,为什么它们存在eekp/seekg?

c++ - 为什么 Clang 会添加额外的 FMA 指令?

c++ - 如何创建一个以另一个模板为模板的模板化类

c++ - 公共(public)接口(interface)中使用的私有(private) typedef

c++ - 我如何将我的类模板专门化为更少的参数