c++function-composition

Couldn't deduce template parameter problem with composing functions in c++


So I wanted to practice composing functions in C++, I have two functions f and g and composition is defined by x ↦ f(g(x)), I implemented the functions with specific data type (int) and it worked and this is the code

int inc(int x) {
    return x + 1;
}

int square (int x) {
    return x * x;
}

function<int (int) > compose(function<int (int) > f, function<int (int) > g) {
    return [=](int x) {
        return f(g(x));
    };
}

int main() {
   auto op = compose(square, inc);
   cout<<op(6)<<"\n";
}

but when I tried to make my functions generic (used templates) I got a compiler error of "couldn't deduce template parameter A" but I am not sure what this means, read couple of articles that had same issue but I don't get them either and here is what I currently have

template<typename A> A inc(A x) {
    return x + 1;
}

template<typename A> A square(A x) {
    return x * x;
}

template<typename A, typename B, typename C>
function<C (A) > compose(function<C (A)> f, function<A (B) > g) {
    return [=](A x) {
        return f(g(x));
    };
}

int main() {
    auto op = compose(square, inc); // <- problem here
    cout<<op(6)<<"\n";
}

Solution

  • The error you encountered, "couldn't deduce template parameter A," is caused by the compiler's inability to deduce the template argument for the function inc.

    The issue arises because you are using the same template parameter A for both inc and square functions in the compose function template. However, when you call compose in the main function, the compiler cannot infer the correct template arguments since inc and square have different template parameter requirements.

    To resolve this error, you should use separate template parameters for each function in the compose function template.

    Your template

    function<int (int) > compose(function<int (int) > f, function<int (int) > g) {
        return [=](int x) {
            return f(g(x));
        };
    }
    

    Replace

    auto op = compose(square, inc);
    

    By

    auto op = compose<int, int, int>(square<int>, inc<int>);