Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Determine the return type of a callable passed to a template

I have a simple wrapper template that allows free functions (e.g. open() close() etc) to passed as template parameters. The code is as follows:

template <auto fn, typename ReturnType=void>
struct func_wrapper {

    template<typename... Args>
    constexpr ReturnType operator()(Args&&... args) const {
        if constexpr( std::is_same<ReturnType, void>::value) {
            fn(std::forward<Args>(args)...);
        } else {
            return fn(std::forward<Args>(args)...);
        }
    }
};

This is used as follows:

    void CloseFunc2(int a);
    into OpenFunc2(const std::string&, int flags);

    using FileWrapper2 = DevFileWrapper<func_wrapper<OpenFunc2, int>,
                                        func_wrapper<CloseFunc2>>;

The code is working fine but I would like to remove the requirement to manually specify ReturnType when creating a func_wrapper.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I tried using std::result_of but that failed because fn is a non type template parameter, e.g.:

template<typename... Args>
constexpr auto operator()(Args&&... args) const 
    -> std::invoke_result<fn(std::forward<Args>(args)...)>::type {
    if constexpr( std::is_same<ReturnType, void>::value) {
        fn(std::forward<Args>(args)...);
    } else {
        return fn(std::forward<Args>(args)...);
    }
}

the error is:

template-parameter-callable.cpp:48:71: error: template argument for 
template type parameter must be a type
constexpr auto operator()(Args&&... args) const ->   
    std::invoke_result<fn(std::forward<Args>(args)...)>::type {                                                                           
                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/
usr/include/c++/v1/type_traits:4009:17: 
note: template parameter is declared here
template <class _Fn, class... _Args>
                ^

1 error generated.

How can I deduce the return type of calling fn at compile time?

>Solution :

template <auto fn>
struct func_wrapper {
    template<typename... Args>
    constexpr decltype(auto) operator()(Args&&... args) const {
      return fn(std::forward<Args>(args)...);
    }
};

have you tried this?

I think that works in . Definitely in .

The return type of a callable cannot be determined unless you also know the arguments you are calling it with.

I can extract the return type, but I don’t think you need it.

template <auto fn>
struct func_wrapper {
    template<typename... Args>
    constexpr decltype(auto) operator()(Args&&... args) const {
      using ReturnType = std::invoke_result_t<
        decltype(fn),
        Args&&...
      >;
      return fn(std::forward<Args>(args)...);
    }
};

but as you can see we don’t need it.

return f(x) when f returns void is (now) legal.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading