有什么方法可以匹配C++ 11中的返回值吗?

Ste*_*eve 5 c++ templates c++11

我试图提供一个调用提供的lambda的函数,我想知道如果函数有返回类型,它是否可以返回默认值void.

这是我到目前为止的函数,它返回lambda的返回值,但如果lambda是void,则返回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;
}
Run Code Online (Sandbox Code Playgroud)

这会产生错误,

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

很明显,这只是因为C++无法使用基于返回类型的多态.但是,我想知道是否有任何好的C++ 11技巧,比如更好地使用decltype或一些模板魔法,这可能会使这成为可能吗?我问,因为据我所知,这里没有真正的歧义..编译器推断void返回类型,然后说是否匹配int或者void版本是不明确的f,这有点傻.

这样做的一个原因是,如果函数f需要返回值但用户提供的lambda不包含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();
}
Run Code Online (Sandbox Code Playgroud)

谢谢!

JKo*_*Kor 3

您可以使用 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第二个。这应该能让你的代码正常工作。我还没有测试过,所以我不确定它是否完全有效。