과부하 해결은 (a) 함수 / 연산자의 이름을 호출하거나 (b) 명시 적 서명으로 포인터를 함수 (또는 함수 또는 멤버 함수)로 캐스팅 할 때만 발생합니다.
여기서도 발생하지 않습니다.
std::function
서명과 호환되는 모든 객체를 가져옵니다 . 구체적으로 함수 포인터를 사용하지 않습니다. 람다는 std 함수가 아니며 std 함수는 람다가 아닙니다.
이제 내 homebrew 함수 변형에서 서명을 R(Args...)
위해R(*)(Args...)
위해 정확히 이런 이유로 인수 (정확한 일치)를 . 그러나 "대응"서명보다 "정확한 일치"서명을 높이는 것을 의미합니다.
핵심 문제는 과부하 세트가 C ++ 객체가 아니라는 것입니다. 오버로드 세트의 이름을 지정할 수 있지만 "네이티브"로 전달할 수는 없습니다.
이제 다음과 같은 함수의 유사 과부하 세트를 작성할 수 있습니다.
#define RETURNS(...) \
noexcept(noexcept(__VA_ARGS__)) \
-> decltype(__VA_ARGS__) \
{ return __VA_ARGS__; }
#define OVERLOADS_OF(...) \
[](auto&&...args) \
RETURNS( __VA_ARGS__(decltype(args)(args)...) )
이렇게하면 함수 이름에서 오버로드 확인을 수행 할 수있는 단일 C ++ 객체가 생성됩니다.
매크로를 확장하면 다음과 같은 이점이 있습니다.
[](auto&&...args)
noexcept(noexcept( baz(decltype(args)(args)...) ) )
-> decltype( baz(decltype(args)(args)...) )
{ return baz(decltype(args)(args)...); }
쓰는 것이 귀찮습니다. 더 간단하고 약간 덜 유용한 버전이 있습니다.
[](auto&&...args)->decltype(auto)
{ return baz(decltype(args)(args)...); }
우리는 많은 수의 인수를 취한 다음에 완벽하게 전달하는 람다가 있습니다 baz
.
그때:
class Bar {
std::function<void()> bazFn;
public:
Bar(std::function<void()> fun = OVERLOADS_OF(baz)) : bazFn(fun){}
};
공장. 우리 fun
는 전달하는 대신에 저장하는 람다에 과부하 해상도를 연기합니다.fun
오버로드 세트를 직접 하는 (해결할 수없는) 시킵니다.
함수 이름을 오버로드 세트 오브젝트로 변환하는 C ++ 언어로 오퍼레이션을 정의하기위한 제안이 하나 이상 있습니다. 이러한 표준 제안서가 표준에 포함될 때까지 OVERLOADS_OF
매크로가 유용합니다.
한 걸음 더 나아가서 호환 기능 캐스트 포인터를 지원할 수 있습니다.
struct baz_overloads {
template<class...Ts>
auto operator()(Ts&&...ts)const
RETURNS( baz(std::forward<Ts>(ts)...) );
template<class R, class...Args>
using fptr = R(*)(Args...);
//TODO: SFINAE-friendly support
template<class R, class...Ts>
operator fptr<R,Ts...>() const {
return [](Ts...ts)->R { return baz(std::forward<Ts>(ts)...); };
}
};
그러나 그것은 모호해지기 시작했다.
라이브 예 .
#define OVERLOADS_T(...) \
struct { \
template<class...Ts> \
auto operator()(Ts&&...ts)const \
RETURNS( __VA_ARGS__(std::forward<Ts>(ts)...) ); \
\
template<class R, class...Args> \
using fptr = R(*)(Args...); \
\
template<class R, class...Ts> \
operator fptr<R,Ts...>() const { \
return [](Ts...ts)->R { return __VA_ARGS__(std::forward<Ts>(ts)...); }; \
} \
}