user2984071
user2984071

Reputation: 1

How to return lambda pointer in a template?

I have to create a template whose return-value is a pointer to some lambda function (which is determined by template parameters).

The compiler feedback:

error: no matching function for call to ‘laptr(int)’

What's wrong with the code? How to solve the problem?

#include <iostream>

using namespace std;

template <typename T>
T laptr(int par);

int main(){
    laptr(1);
    return 0;
}

///////////

template <typename T>
T laptr(int par)
{
    if (par == 1)
    {
        int p1 = [](int a, int b)->int{return a*b; };
        return p1;
    }
    else
    {
        double p2 = [](double a, double b)->double{return a + b; };
        return p2;
    }
}

Upvotes: 0

Views: 180

Answers (2)

Jerry Coffin
Jerry Coffin

Reputation: 490308

Your fundamental problem is that:

template <typename T>

...here, T is/must be determined entirely at compile time, but:

T laptr(int par)

par isn't known until run time, and:

if (par == 1)
{
    int p1 = [](int a, int b)->int{return a*b; };
    return p1;
}
else
{
    double p2 = [](double a, double b)->double{return a + b; };
    return p2;
}

Here, T isn't known until you've decided which leg of the if statement to execute, so the type 1) must be known before the code finishes compiling, not to mention anything about executing, but 2) can't be determined until the code executes.

Obviously you can't have both of those happen, so the code can't compile.

There are quite a few alternatives -- a pointer to a function, a std::function, a Command object (as defined in Modern C++ Design), etc. All of them will do the job essentially similarly: rather that attempting to return the precise type of each lambda, they're going to define some common type that can hold the type of either lambda, and return an object of that type instead.

Upvotes: 3

masoud
masoud

Reputation: 56499

You can use a std::function to store a lambda function:

template <typename T>
std::function<T(T,T)> laptr (int par)
{
    if(par == 1)
        return [](T a, T b)->T {return a*b;};
    else
        return [](T a, T b)->T {return a+b;};
}

or even a pointer to function

template <typename T>
auto laptr (int par) -> T(*)(T,T)
{
    ...
}

 

You can use it like this

auto func = laptr<double>(1);

auto result = func(8,2); // 8*2=16

Upvotes: 5

Related Questions