简体   繁体   中英

C++ member function with auto and default arguments

I am trying to implement a member function in a C++ class which has an auto argument (a lambda) and an int argument with a default value. Something like this:

class Base {
public:
    int add_one(auto fobj, int b=3);
};

int Base::add_one(auto add_fcn, int b) {
    return add_fcn(1, b);
}

However, a simple test like this fails to compile:

#include <iostream>

class Base {
public:
    int add_one(auto fobj, int b=3);
};

int Base::add_one(auto add_fcn, int b) {
    return add_fcn(1, b);
}

int main() {
    int ans;
    auto add_fcn = [](int a, int b) -> int {return a + b;};
    Base obj;
    ans = obj.add_one(add_fcn);
    std::cout << ans << "\n";
    return 0;
}

The error the compiler (MinGW 7.2.0, flags: -std=c++14) gives me is the following:

error: call to 'int Base::add_one(auto:2, int) [with auto:1 = main()::<lambda(int, int)>]' uses the default argument for parameter 2, which is not yet defined

I sincerely do not understand the error. Can someone please explain me the reason of this error and how it can be fixed? Thank you in advance.

auto parameters is a gcc extension. It means that it is not a standard compliant way to solve the problem.

I am not sure what is the exact reason for the error above, but you might achieve the same effect with template member function which works well:

class Base {
public:
    template<typename F>
    int add_one(F fobj, int b = 3);
};

template<typename F>
int Base::add_one(F add_fcn, int b) {
    return add_fcn(1, b);
}

Wandbox example

Another possible way is to use std::function (which implies some performance overhead though):

class Base {
public:
    int add_one(std::function<int(int, int)> fobj, int b = 3);
};

int Base::add_one(std::function<int(int, int)> add_fcn, int b) {
    return add_fcn(1, b);
}

Wandbox example

Finally, you could make use of pointers to functions, but it is too C way...


If you'd like to expand your knowledge on passing functions to functions, this article by Vittorio Romeo gives an excellent explanation + some benchmarks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM