나는 제공된 람다를 호출하는 함수를 제공하려고 노력하고 있으며 함수에 반환 유형이 void
인 경우이 함수가 기본값을 반환 할 수 있는지 궁금합니다. 여기 C++ 11에서 반환 값을 비교하는 방법은 무엇입니까?
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
또는 void
버전을 f
과 일치 시킬지 모르는 것을 말합니다. 이는 다소 바보입니다.
이 일을하는 이유는 기능 f
는 반환 값을 기대하지만, 사용자가 return
문을 포함하지 않는 람다를 제공하는 경우, 컴파일러가 void
유형을 유추하고, 오류가 밖으로 것입니다. 실제 시나리오에서는 합리적인 기본 반환 값이 사용자가 하나를 제공하지 않을 때 어떤 값을 가져야하는지에 대한 좋은 생각을 가지고 있기 때문에 사용자가 자주 불필요한 return
문을 무시하도록 컴파일러를 사용할 수 있는지 궁금합니다. 편의상.
감사합니다. GCC 4.6.3을 사용하고 있음을 언급해야합니다.
대답 :
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();
}
감사 : enable_if
를 사용 Xeo의 제안에 따라, 나는 작동하는 것 같다 다음, 함께 왔어요!
당신이 정상적인 기능에 F를 테스트 한 같은 aswell
작업을하게? – CharlesB
예, 일반적인 기능에서는 모호합니다. – Steve
'decltype'의 두 번째 매개 변수 : 그것이 무엇인지 물어볼 수 있습니까? (정말로, 내가 모르기 때문에!). – 0x499602D2