M.K. aka Grisu
M.K. aka Grisu

Reputation: 2398

C++ compile code depending on the concrete type of auto

I have a C++ piece of code

auto returnvalue = m_func(x, y, z); 

where the type of m_func depends on a template parameter. Afterwards I deal with the returnvalue which works fine until m_func is a function returning void. But I need a mechanism which calls

m_func(x,y,z)

if the return value of m_func is void and the above version is not. Overall in pseudo code it need to look like

if ( returnvalue of m_func is void ) 
     call m_func directly
else 
     auto retval = m_func(...) 
     handle the return value

How can these be done with C++11/14?

Edit:

m_func is either:

void func(type1 arg1, type2 arg, ...) 

or

std::tuple<...> func(type1 arg1, type2 arg, ...) 

Upvotes: 4

Views: 205

Answers (2)

Jarod42
Jarod42

Reputation: 217850

Whereas C++17 has if constexpr to handle it simply, C++11/C++14 has to use some overload to handle it via SFINAE or tag dispatching or specialization, follow up a tag dispatching version:

void internal_impl(std::true_type/*, ... */) {
    m_func(x, y, z);
}
void internal_impl(std::false_type/*, ... */) {
    auto value = m_func(x, y, z);

    foo(value);
}

void internal(/*... */) {
    internal_impl(std::integral_constant<bool,
                                         std::is_void<decltype(m_func(x, y, z))>::value>{}
                  /*, ...*/);
}

Upvotes: 4

eerorika
eerorika

Reputation: 238401

Prior to C++17, you can use template specialisation:

template<class R>
struct handle {
    template<class F>
    static void the_return_value(F m_func) {
        auto retval = m_func(x, y, z);
        // handle the return value
    }
};

template<>
struct handle<void> {
    template<class F>
    static void the_return_value(F m_func) {
        m_func(x, y, z);
    }
};

// usage
using R = decltype(m_func(x, y, z));
handle<R>::the_return_value(m_func);

In C++17, you can use if constexpr instead:

using R = decltype(m_func(x, y, z));
if constexpr (std::is_void_v<R>) {
    m_func(x, y, z);
} else {
    auto retval = m_func(x, y, z);
    // handle the return value
}

Upvotes: 4

Related Questions