简体   繁体   中英

Why can't compiler deduce types from templates like template<typename R(typename… Args)>?

For me it would look natural that the compiler could deduce types of templates like this:

template<typename R(typename... Args)>
struct wrap {
    std::function<R(Args)> func_;

    template<typename... Args2>
    wrap(Args2&& ...args2) : func_(std::forward<Args2>(args2)...) {
    }

    R operator()(Args&&... args) {
        cout << "Extra stuff that wrap template does" << endl;
        return func_(std::forward<Args>(args)...);
    }
}

So I can instantiate with any function without explicitly giving its signature to the template:

wrap w([](int x){ return 2*x });

And call it easily:

w(3);

But it turns out that this kind of wrapping does not work at all. GCC 4.8.1 says expected nested-name-specifier before 'R' .

Why this is not possible? What would be the way to achieve this kind of generic wrapping functionality?

There are proposals to do something like this in C++1y, whose state I am not current on.

Your syntax is not right for those proposals, as a lambda is the wrong type to instantiate a std::function template with. It wants a signature, not the type of some lambda.

Writing a make_wrap is possible, but requires taking the lambda type and extracting the args and return value yourself. It is also rarely a good idea, because if the only way you know a std::function s type is from deduction, in that context why type erase it? Instead, carry the raw lambda type around.

There are reasons to want to do that, but they are rarely good.

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