使用cv-qualifiers和ref-qualifiers

时间:2017-05-19 02:46:37

标签: c++ typetraits

根据C++ reference,这是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 {};

但是,对成员函数使用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;
}

据我了解,cv-qualifiers和ref-qualifiers仅适用于类成员函数。

所以我的问题是,为什么std::is_function的实现专门针对所有不同的cv限定符和ref-qualifiers,因为它不考虑成员函数&#34;函数&#34;开始?

更新

根据下面的答案,我决定做一个实验。我实现了自己的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;

然后我改变了X::Test的签名:

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

使用答案中提供的function_traits结构,然后我尝试了这个:

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

在这种情况下, x 为false。但是如果我为我的IsFunction添加const的特化:

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

然后x将 true !所以过载很重要。但我不确定我理解为什么,或function_traits如何最终转换成一个&#34;成员函数指针&#34;一个&#34;成员函数&#34;,它与常规函数真的不一样,是......?

2 个答案:

答案 0 :(得分:4)

  

据我了解,cv-qualifiers和ref-qualifiers仅适用于类成员函数。

虽然非成员函数不能包含cv-qualifiers或ref-qualifiers,但函数类型仍然可以包含它们而不必绑定到特定的类类型。

df['Col1'].update(df['Col2'])
print (df)
   Col1  Col2
0   8.0     8
1   9.0     9
2   7.0     7
3  10.0    10

此处,typedef void fc() const; struct S { fc f; }; void S::f() const { } 应为std::is_function_v<fc>

答案 1 :(得分:2)

这不是问题的直接答案,但显示了如何从成员函数类型中删除该类。

您可以通过简单的类型特征从成员函数中删除类实例,以使该函数与is_function兼容。这显然是必要的,因为

  

std::function,lambdas,带有重载operator()的类和函数指针等类型不算作函数类型。

     

<子> Re-opening Console View in Eclipse as of Mars.2 Release (4.5.2)

#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';
}

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