我正在尝试提供一个调用提供的 lambda 的函数,我想知道如果该函数具有 return type ,是否可以让它返回一个默认值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;
}
这会产生错误,
test.cpp:20:68: error: call of overloaded ‘f(main()::<lambda()>)’ is ambiguous
很明显,这只是由于 C++ 无法使用基于返回类型的多态性。但是,我想知道是否有任何好的 C++11 技巧,例如更好地使用decltype
或一些模板魔术,这可能会使这成为可能?我之所以问,是因为据我所知,这里没有真正的歧义。编译器正在推断void
返回类型,然后说是否匹配int
or的void
版本是模棱两可的f
,这有点愚蠢。
这样做的一个原因是,如果函数f
需要一个返回值,但用户提供了一个不包含return
语句的 lambda,编译器会推断出一个void
类型,然后会出错。因为在实际场景中,我很清楚当用户不想提供一个合理的默认返回值时,我想知道是否有可能让编译器允许用户忽略经常不必要的return
语句方便。
谢谢。我应该提到我正在使用 GCC 4.6.3。
答:根据 Xeo 的 using 建议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();
}
谢谢!