将lambda函数作为模板参数传递给函数指针的函数模板

10

看起来我不能将一个不捕获变量的lambda表达式作为模板参数传递给一个函数指针模板函数。我是做错了什么,还是这是不可能的?

#include <iostream>

// Function templated by function pointer
template< void(*F)(int) >
void fun( int i )
{
    F(i);
}

void f1( int i )
{
    std::cout << i << std::endl;
}

int main()
{
    void(*f2)( int ) = []( int i ) { std::cout << i << std::endl; };

    fun<f1>( 42 ); // THIS WORKS
    f2( 42 );      // THIS WORKS
    fun<f2>( 42 ); // THIS DOES NOT WORK (COMPILE-TIME ERROR) !!!

    return 0;
}

使用std::function - 101010
1
f2是一个变量 - 运行时参数。模板需要构建时参数(常量和类型)。尝试添加const,但可能不起作用。 - Hcorg
2个回答

11

大多数情况下,这是语言定义中的问题,以下内容更加明显:

using F2 = void(*)( int );

// this works:
constexpr F2 f2 = f1;

// this does not:
constexpr F2 f2 = []( int i ) { std::cout << i << std::endl; };

Live example

这基本上意味着您的希望/期望是相当合理的,但当前的语言并不是定义为这样 - lambda不会产生适用于constexpr的函数指针。

然而,有一个提案来解决这个问题:N4487


4

这是不可行的,因为f2不是constexpr(即运行时变量)。因此,它不能用作模板参数。您可以通过以下方式改变代码并使其更加通用:

#include <iostream>

template<typename F, typename ...Args>
void fun(F f, Args... args) {
  f(args...);
}

void f1( int i ) {
    std::cout << i << std::endl;
}

int main() {
    auto f2 = []( int i ) { std::cout << i << std::endl; };
    fun(f1, 42);
    f2( 42 );
    fun(f2, 42 );
    return 0;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接