10

Looks like I cannot pass a no-capture lambda as a template parameter to a templated by function-pointer function. Am I doing it the wrong way, or is it impossible?

#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;
}
2
  • Use std::function. Commented Jun 24, 2015 at 16:29
  • 1
    f2 is a variable - runtime parameter. Templates require build time parameters (constants and types). Try adding const, but it probably won't work. Commented Jun 24, 2015 at 16:32

2 Answers 2

11

It's mostly a problem in the language's definition, the following makes it more obvious:

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

This basically means that your hope/expectation is quite reasonable, but the language is currently not defined that way - a lambda does not yield a function pointer which is suitable as a constexpr.

There is, however, a proposal to fix this issue: N4487.

Sign up to request clarification or add additional context in comments.

Comments

4

This is not viable because f2 is not constexpr (i.e., is a runtime variable). As such it cannot be used as a template parameter. You could alter your code and make it more generic in the following manner:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.