简体   繁体   English

用cv-qualifiers和ref-qualifiers实现std :: is_function

[英]Implementation of std::is_function with cv-qualifiers and ref-qualifiers

According to the C++ reference , this is a valid implementation of std::is_function (excluding the partial specializations for variadic functions and noexcept specifiers for brevity): 根据C ++参考 ,这是std::is_function的有效实现(不包括可变参数函数的部分专业化,为了简洁起见, noexcept指定符):

template<class>
struct is_function : std::false_type { };

// specialization for regular functions
template<class Ret, class... Args>
struct is_function<Ret(Args...)> : std::true_type {};

// specialization for function types that have cv-qualifiers
template<class Ret, class... Args>
struct is_function<Ret(Args...)const> : std::true_type {};
template<class Ret, class... Args>
struct is_function<Ret(Args...)volatile> : std::true_type {};
template<class Ret, class... Args>
struct is_function<Ret(Args...)const volatile> : std::true_type {};

// specialization for function types that have ref-qualifiers
template<class Ret, class... Args>
struct is_function<Ret(Args...) &> : std::true_type {};
template<class Ret, class... Args>
struct is_function<Ret(Args...)const &> : std::true_type {};
template<class Ret, class... Args>
struct is_function<Ret(Args...)volatile &> : std::true_type {};
template<class Ret, class... Args>
struct is_function<Ret(Args...)const volatile &> : std::true_type {};
struct is_function<Ret(Args...) &&> : std::true_type {};
template<class Ret, class... Args>
struct is_function<Ret(Args...)const &&> : std::true_type {};
template<class Ret, class... Args>
struct is_function<Ret(Args...)volatile &&> : std::true_type {};
template<class Ret, class... Args>
struct is_function<Ret(Args...)const volatile &&> : std::true_type {};

However, using std::is_function on member functions returns false : 但是,在成员函数上使用std::is_function返回false

struct X
{
    int Test(float)
    {
        return 0;
    }
};

int main()
{
    auto x = std::is_function_v<decltype(&X::Test)>; // x is 'false'
    return 0;
}

As far as I understand it, cv-qualifiers and ref-qualifiers are only applicable to class member functions. 据我了解,cv限定词和ref限定词仅适用于类成员函数。

So my question is, why does the implementation of std::is_function specialize for all the different cv-qualifiers and ref-qualifiers when it doesn't consider member functions "functions" to begin with? 所以我的问题是,当std::is_function的实现不考虑成员函数“ functions”开头时,为什么它专门针对所有不同的cv限定词和ref限定词?

Update: 更新:

Based on the answer below, I decided to do an experiment. 根据下面的答案,我决定做一个实验。 I implemented my own minimal version of std::is_function : 我实现了自己的最小版本的std::is_function

template <class T>
struct IsFunction :
    std::integral_constant<bool, false>
{
};

template <class R, class... A>
struct IsFunction<R(A...)> :
    std::integral_constant<bool, true>
{
};

template <class T>
constexpr bool IsFunctionV = IsFunction<T>::value;

And then I changed the signature of X::Test : 然后我更改了X::Test的签名:

struct X
{
    int Test(float) const
    {
        return 0;
    }
};

Using the function_traits struct provided in the answer, then I tried this: 使用答案中提供的function_traits结构,然后尝试了此操作:

auto x = IsFunctionV<function_traits<decltype(&X::Test)>::type>;

In this case, x is false. 在这种情况下, x为假。 But if I add a specialization for const to my IsFunction as such: 但是,如果我像这样向我的IsFunction添加const的IsFunction

template <class R, class... A>
struct IsFunction<R(A...) const> :
    std::integral_constant<bool, true>
{
};

Then x will be true ! 那么x将为 So the overload is important. 因此,过载很重要。 But I'm not sure I understand why, or how function_traits ends up converting a "member function pointer" to a "member function", which isn't really the same as a regular function, is it...? 但是我不确定我理解为什么,或者function_traits最终如何将“成员函数指针”转换为“成员函数”,这与常规函数并不完全相同,是吗?

As far as I understand it, cv-qualifiers and ref-qualifiers are only applicable to class member functions. 据我了解,cv限定词和ref限定词仅适用于类成员函数。

Although non-member functions cannot have cv-qualifiers or ref-qualifiers, function types can still contain them without being bound to a specific class type. 尽管非成员函数不能具有cv限定符或ref限定符,但函数类型仍可以包含它们而不绑定到特定的类类型。

typedef void fc() const;
struct S { fc f; };
void S::f() const { }

Here, std::is_function_v<fc> is supposed to be true . 在这里, std::is_function_v<fc>应该是true

This is not a direct answer to the question but shows how you can remove the class from the member function type. 这不是问题的直接答案,而是说明了如何从成员函数类型中删除该类。


You can remove the class instance from the member function by a simple type trait to make the function compatible with is_function . 您可以通过简单的类型特征从成员函数中删除类实例,以使该函数与is_function兼容。 This is clearly necessary because 这显然是必要的,因为

Types like std::function , lambdas, classes with overloaded operator() and pointers to functions don't count as function types. 诸如std::function ,lambdas,具有重载operator()以及指向函数的指针之类的类型均不算作函数类型。

http://en.cppreference.com/w/cpp/types/is_function http://en.cppreference.com/w/cpp/types/is_function

#include <iostream>
#include <type_traits>

template < typename T >
struct function_traits { typedef T type; };

template < typename T, typename C >
struct function_traits < T(C::*) > { typedef T type; };

struct X
{
    int Test(float)
    {
        return 0;
    }
};

int test(float) { return 1; }

int main()
{
    std::cout << std::boolalpha;

    auto x = std::is_function< decltype(&X::Test) >::value;
    std::cout << x << '\n';

    auto y = std::is_function< function_traits<decltype(&X::Test)>::type >::value;
    std::cout << y << '\n';

    auto z = std::is_function< function_traits<decltype(test)>::type >::value;
    std::cout << z << '\n';
}

Demo on Wandbox Wandbox上的演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM