c++ - 检测模板化 operator() 的限定符

标签 c++ templates c++11

我正在寻找一种特征来检测和提取模板化运算符的完整签名(以检查方法限定符volatileconst)( )

这意味着 std::bind 表达式(不使用 std::is_bind_expression)和带有自动参数的 lambda。 预期的返回类型和参数是已知的

例如:

template<typename Fn, typename T>
struct is_templated_functor { ... };

auto fun = [](auto) mutable { };
using ty = decltype(&decltype(fun)::operator()<int>);
// ty = void(decltype(fun)::*)(int)
// lambda is mutable ~~~~~~~~~~~~~~~^^^^^^
is_templated_functor<void(int), decltype(fun)>::value == true;

auto fun2 = std::bind([](int) { });
using ty2 = decltype(&decltype(fun2)::operator()<int>);
// ty2 = void(decltype(fun2)::*)(int) const
is_templated_functor<void(int), decltype(fun2)>::value == true;

最佳答案

由于@Yakk 的评论,我意识到我不需要获得表达式的完整签名来检查表达式是否可以使用 const 和/或 volatile 限定符,因为返回类型和参数是已知的。

可以使用检测成语来检查具有模板化 operator() 的对象是否可以使用给定的限定符调用:

template<typename Fn>
struct impl_is_callable_with_qualifiers;

template<typename ReturnType, typename... Args>
struct impl_is_callable_with_qualifiers<ReturnType(Args...)>
{
    template<typename T>
    static auto test(int)
        -> typename std::is_convertible<
            decltype(std::declval<T&>()(std::declval<Args>()...)),
            ReturnType
           >;

    template<typename T>
    static auto test(...)
        -> std::false_type;
};

template<bool Condition, typename T>
using add_const_if_t = typename std::conditional<
    Condition,
    typename std::add_const<T>::type,
    T
>::type;

template<bool Condition, typename T>
using add_volatile_if_t = typename std::conditional<
    Condition,
    typename std::add_volatile<T>::type,
    T
>::type;

template<typename T, typename Fn, bool Constant, bool Volatile>
using is_callable_with_qualifiers = decltype(impl_is_callable_with_qualifiers<Fn>::template test<
    add_volatile_if_t<Volatile, add_const_if_t<Constant, typename std::decay<T>::type>>
>(0));

使用示例:

struct callable
{
    void huhu(int) const { }
};

auto fun = [](auto) mutable { };
static_assert(is_callable_with_qualifiers<decltype(fun), void(int), false, false>::value, "1 failed");
static_assert(!is_callable_with_qualifiers<decltype(fun), void(int), true, true>::value, "2 failed");

auto fun2 = std::bind(&callable::huhu, callable{}, std::placeholders::_1);

// std::bind isn't const correct anyway...
static_assert(is_callable_with_qualifiers<decltype(fun2), void(int), false, false>::value, "3 failed");
static_assert(is_callable_with_qualifiers<decltype(fun2), void(int), true, false>::value, "4 failed");
static_assert(!is_callable_with_qualifiers<decltype(fun2), void(int), true, true>::value, "5 failed");

Demo

关于c++ - 检测模板化 operator() 的限定符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32526163/

相关文章:

c++ - 简单的数学解析器 Flex&Bison

使用模板的 C++ 11 异步编程

c++ - 为什么 vector 访问运算符没有指定为 noexcept?

c++ - lambda 运算符重载?

c++ - 使用指针时表达式必须具有类类型

c++ - Xcode 显示 C++ 继承的 "Use of undeclared Identifier"错误

c++ - 'strcpy' 错误和警告

C++:返回类型为 T 且不采用 T 类型参数的模板函数将无法编译

c++ - 如何根据 T::key_type 的定义专门化类模板?

c++ - 仿函数/函数对象的 is_function 类型特征