C ++ - 在模板化函数指针参数调用中确定foo的实例

时间:2015-08-22 15:57:29

标签: c++ c++11 function-pointers

我正在玩函数指针调用和回调,并尝试编写一个可以接受任何函数指针的函数,记录函数调用并在之后调用函数指针。这是一个代码,向您展示我尝试做的事情:

#include<iostream>
#include<string>
#include<functional>

int foo4(std::function<int(int)> Fn, int&& val)
{
    return Fn(std::forward<int>(val));
}

template<typename Fn>
int foo5(Fn fn)
{
    return 10;
}

template <typename T, typename... args>
T(*LogAndCall(T(*ptr)(args...)))(args...)
{
    std::cout << "Logging function call to: " << ptr << " with " << sizeof...(args) << " argument(s)" << std::endl;
    return ptr;
}

int main()
{
    //call func1
    auto r4 = LogAndCall(foo4)([](int&& x) {
        return x * 10;
    }, 100);
    std::cout << "Ret value: " << r4 << std::endl << std::endl;

    //call foo5
    auto r5 = LogAndCall(foo5<specialization?>)([](int x) { //<--- problem
        return x;
    });

    std::cin.get();
    return 0;
}

正如您所看到的,问题是调用foo5时出现以下错误:

看起来我需要指定foo5<something>,但问题是,什么? :)

1 个答案:

答案 0 :(得分:2)

  

看起来我需要指定foo5<something>,但问题是,什么?

对于非捕获lambda,您可以强制衰减为指针:

auto r5 = LogAndCall(foo5<int(int)>)([](int x){
//                        ~~~~~~~^
    return x;
});

如果它是一个捕获lambda,你可以使用类型擦除技术:

auto r6 = LogAndCall(foo5<std::function<int(int)>>)([&](int x){
//                        ~~~~~~~~~~~~~~~~~~~~~~^
    return x;
});

或者,您可以将lambda存储到变量中,以便可以使用decltype()说明符查询其类型:

auto lambda = [&](int x){
    return x;
};
auto r7 = LogAndCall(foo5<decltype(lambda)>)(lambda);
//                        ~~~~~~~~~~~~~~~^

DEMO