函数vs lambda作为函数参数

时间:2017-11-29 12:45:37

标签: c++ c++14

我正在尝试使用新的C ++标准进行练习,但我很难诊断出这里发生了什么:

https://godbolt.org/g/x6mNmc

#include <iostream>

template <std::size_t N, typename T0, typename ... Ts>
struct typeN { using type = typename typeN<N-1U, Ts...>::type; };

template <typename T0, typename ... Ts>
struct typeN<0U, T0, Ts...> { using type = T0; };

template <std::size_t, typename>
struct argN;

template <std::size_t N, typename R, typename ... As>
struct argN<N, R(As...)> { using type = typename typeN<N, As...>::type; };

template <typename>
struct returnType;

template <typename R, typename ... As>
struct returnType<R(As...)> { using type = R; };

template<std::size_t N, typename R>
using arg_type = typename argN<N,R>::type;

// Here
struct Dummy {
    int x;
};

struct A {
    Dummy dummy;
};

void something(decltype(A::dummy)&a, int32_t in) {
    a.x = in;
}

auto something_l = [](decltype(A::dummy)&a, int32_t in) -> void {
    a.x = in;
};

template<typename T>
auto get_something(A& a, T& f) {
    return [&](arg_type<0, T> s) {
        f(a.dummy, 1);
    };
};

template<typename T>
auto get_something_l(A& a, T f) {
    return [&](arg_type<0, decltype (T::operator())> s) {
        f(a.dummy, 1);
    };
};

int main()
{
    A a;
    auto ds = get_something(a, something);
    //auto ds_l = get_something_l(a, something_l);
    auto ds_l2 = get_something_l(a, [](decltype(A::dummy)&a, int32_t in) -> void {
            a.x = in;
        }
    );

}

编译器(gcc 6.3.0 -std = c ++ 1y)说我:

In instantiation of 'struct get_something_l(A&, T) [with T = main()::<lambda(Dummy&, int32_t)>]::<lambda>':
52 : <source>:52:5:   required from 'auto get_something_l(A&, T) [with T = main()::<lambda(Dummy&, int32_t)>]'
63 : <source>:63:5:   required from here
50 : <source>:50:55: error: invalid use of non-static member function 'main()::<lambda(Dummy&, int32_t)>'
     return [&](arg_type<0, decltype (T::operator())> s) {
                                                       ^
<source>: In instantiation of 'auto get_something_l(A&, T) [with T = main()::<lambda(Dummy&, int32_t)>]':
63 : <source>:63:5:   required from here
50 : <source>:50:12: error: member 'get_something_l(A&, T) [with T = main()::<lambda(Dummy&, int32_t)>]::<lambda>::<f capture>' is uninitialized reference
     return [&](arg_type<0, decltype (T::operator())> s) {
            ^
50 : <source>:50:12: error: member 'get_something_l(A&, T) [with T = main()::<lambda(Dummy&, int32_t)>]::<lambda>::<a capture>' is uninitialized reference
Compiler exited with result code 1

我想我已经知道它发生了什么,即使我找不到解决方案,如果有的话......

1 个答案:

答案 0 :(得分:1)

首先,T::operator()不是有效的语法;要形成指向成员的指针,请使用&T::operator()

其次,argN专门用于常规函数,但不适用于指向成员函数的指针;两者不是一回事。添加

template <std::size_t N, typename T, typename R, typename ... As>
struct argN<N, R(T::*)(As...)> { using type = typename typeN<N, As...>::type; };

template <std::size_t N, typename T, typename R, typename ... As>
struct argN<N, R(T::*)(As...) const> { using type = typename typeN<N, As...>::type; };

通过这些更改,your code compiles