Any way to match return value in C ++ 11?

I am trying to provide a function that calls the provided lambda, and I wonder if it can return the default if the function has a return type void.

Here is what I have so far, a function that returns the return value of a lambda, but if it is a lambda void, then it returns 20.

#include <functional>
#include <iostream>

template <typename H>
auto f(H&& h) -> decltype(h(), void())
{
    return h();
}

template <typename H>
auto f(H&& h) -> decltype(h(), int())
{
    h();
    return 20;
}

int main()
{
    int r = f([](){ std::cout << "test1" << std::endl; return 10; }); // error here
    std::cout << "r: " << r << std::endl;
    r = f([](){ std::cout << "test2" << std::endl; });
    std::cout << "r: " << r << std::endl;

    return 0;
}

This results in an error

test.cpp:20:68: error: call of overloaded ‘f(main()::<lambda()>)’ is ambiguous

, , ++ . , , - ++ 11, , decltype , ? , , , .. void, , , int void f, .

, f , , return, void . , , , , return .

. , GCC 4.6.3.

: Xeo enable_if, , , , :

template <typename H>
auto f(H&& h) -> typename std::enable_if<std::is_same<decltype(h()), void>::value, int>::type
{
    h();
    return 20;
}

template <typename H>
auto f(H&& h) -> typename std::enable_if<std::is_same<decltype(h()), int>::value, int>::type
{
    return h();
}

!

+5
2

std:: enable_if.

std::enable_if<!std::is_same<decltype(h()), void>::value, decltype(h())>:type , std::enable_if<std::is_same<decltype(h()), void>::value, int>::type . . , , .

+3

, , , ? ++ , . .

STL:

TL;DR: ! , , .

(template<class T> void f(T&&);) - , .

, @JKor SFINAE, :

#include <type_traits>

template<class F>
auto f(F f)
  -> decltype(true? f() : void())
{
  f();
}

template <class F>
auto f(F f) -> decltype(int(f()))
{
  f();
  return 42;
}

int main(){
  f([]{});
}

, GCC 4.7 , decltype(int(void_returning_function())) SFINAE. Clang 3.1

f([]{});

f([]{ return 42; });
+2

All Articles