Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C+;中返回值的任何匹配方法+;11?_C++_Templates_C++11 - Fatal编程技术网

C++ C+;中返回值的任何匹配方法+;11?

C++ C+;中返回值的任何匹配方法+;11?,c++,templates,c++11,C++,Templates,C++11,我试图提供一个调用提供的lambda的函数,我想知道如果该函数具有返回类型void,是否可以让它返回默认值 到目前为止,我得到了一个函数,它返回lambda的返回值,但是如果lambda是void,那么它返回20 #include <functional> #include <iostream> template <typename H> auto f(H&& h) -> decltype(h(), void()) { retu

我试图提供一个调用提供的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;
}

谢谢

如果需要,可以使用std::enable\u


您的返回类型将是
std::enable_if::value,decltype(h())>:type
用于第一个,而
std::enable_if::type
用于第二个。这应该可以让你的代码正常工作。我还没有测试它,所以我不确定它是否能完全工作。

请给出一个理由,说明为什么编译器应该能够根据您在函数中所做的操作推断选择哪个重载?在C++中,只有每个参数与参数匹配时,过载解析才是唯一的。函数的返回类型和内容都不感兴趣

:

TLDR:模板是贪婪的!除非你完全确定会发生什么,否则不要让它们过载

而作为参数的通用引用(
template 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([]{});
}
工作,以及

f([]{ return 42; });

你在正常函数上测试过f吗?是的,在正常函数上它也是不明确的。
decltype
的第二个参数:我能问一下它的用途吗?(真的,因为我不知道!)@Steve:不,这是正确的。我想你可能在什么地方打错了。请参阅。@Xeo:啊,谢谢,我认为JKor解决方案第一部分中的第二个
decltype(h())
是有问题的,因为它更改了
f()
的返回值。我根据你的例子让它工作,我将在问题中发布代码。
#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([]{});
}
f([]{});
f([]{ return 42; });