在C ++ 14

时间:2015-12-27 14:57:52

标签: c++ function templates metaprogramming c++14

我想知道是否可以“模式匹配”函数和可调用对象来提取(在编译时)函数的参数个数。 换句话说,我想创建一个名为 count_arg 的元函数 返回传递函数的参数个数。

考虑以下代码:

#include <iostream>
#include <functional>
#include <type_traits>

#define LIFT_FUN(f) decltype(f)


template<typename T>
struct count_arg : public count_arg<decltype(&T::operator())>
{
};


template<typename R, typename ...Args>
struct count_arg<R(Args...)>
{
    static const size_t value = sizeof...(Args);
};

template <typename C, typename R, typename... Args>
struct count_arg<R(C::*)(Args...) const>
{
    static const size_t value = sizeof...(Args);
};

template<typename R, typename ...Args>
struct count_arg<R(*)(Args...)>
{
    static const size_t value = sizeof...(Args);
};

template<typename R, typename ...Args>
struct count_arg<R(&)(Args...)>
{
    static const size_t value = sizeof...(Args);
};


template <typename T>
struct show_type;


template <typename F>
decltype(auto) flip(F f)
{
    return [f](auto a, auto b){
        return f(b, a);
    };
}


int minus(int a, int b, int c)
{
    return a - b + c;
}


struct Minus
{
    int operator()(int a, int b) const
    {
        return a - b;
    }
};


int main()
{
    int a{5}, b{3};
    auto g = [](int a, int b){
        return a - b;
    };

    auto fmin = flip(g);

    std::cout << minus(a, b, 0) << std::endl;
    std::cout << fmin(a, b) << std::endl;

    std::cout << "minus arity:" << count_arg<LIFT_FUN(minus)>::value << std::endl;
    std::cout << "    g arity:" << count_arg<LIFT_FUN(g)>::value << std::endl;
    std::cout << "Minus arity:" << count_arg<LIFT_FUN(Minus{})>::value << std::endl;
}

此示例有效,但如果我尝试 fmin

std::cout << " fmin arity:" << count_arg<LIFT_FUN(fmin)>::value << std::endl;

(使用g ++ 4.9.2:g ++ flip.cpp -o flip -std = c ++ 14) 我收到了这个错误:

flip.cpp: In instantiation of ‘struct count_arg<flip(F) [with F = main()::<lambda(int, int)>]::<lambda(auto:1, auto:2)> >’:
flip.cpp:83:61:   required from here
flip.cpp:9:8: error: decltype cannot resolve address of overloaded function
 struct count_arg : public count_arg<decltype(&T::operator())>
        ^
flip.cpp: In function ‘int main()’:
flip.cpp:83:36: error: ‘value’ is not a member of ‘count_arg<flip(F) [with F = main()::<lambda(int, int)>]::<lambda(auto:1, auto:2)> >’
     std::cout << " fmin arity:" << count_arg<LIFT_FUN(fmin)>::value << std::endl;

有什么想法吗?

修改

根据Vittorio的建议,我尝试了get_arity实现(Get function arity from template parameter):

std::cout << "   g arity:" << get_arity<decltype(g)>::value << std::endl;
std::cout << "fmin arity:" << get_arity<decltype(fmin)>::value << std::endl;

但我仍然遇到 fmin 的问题。 如果我以这种方式更改翻转(返回的lambda不是更通用的):

template <typename F>
decltype(auto) flip(F f)
{
    return [f](int a, int b){
        return f(b, a);
    };
}

我的代码编译......

所以我现在的问题是我必须找到一种方法从 通用lambdas 中提取数字og参数。 有什么想法吗?

0 个答案:

没有答案