질문이 동일하게 유지됩니다. - 인수를 지정하지 않거나 언급 된 트릭을 사용하지 않고 오버로드 된 멤버 함수를 감지 할 수 있습니까? 나는 어쩌면 불가능을 요구하고 있을지도 모른다. 그러나 묻는 것은 결코 아프지 않다.
실제로, 불가능하지 않다.
그것은 최소한의 작업 예를 들어 다음과 같습니다
template<typename T, typename R, typename... A>
void proto(R(T::*)(A...));
template<typename, typename = void>
constexpr bool has_single_f = false;
template<typename T>
constexpr bool has_single_f<T, decltype(proto(&T::f))> = true;
struct S {
void f(int) {}
void f(char) {}
};
struct U {
void f() {}
};
int main() {
static_assert(not has_single_f<S>, "!");
static_assert(has_single_f<U>, "!");
}
은 물론, 당신은 구성원 방법과 데이터 멤버를 구분하기 위해 더 많은 물건을 추가 할 필요를하지만 (헤더 type_traits
참조)을 추가하는 사소한 내가 시도 예제를 가능한 한 최소로 유지합니다.
기본 아이디어는 주어진 함수가 오버로드 된 경우 proto
에 대한 호출이 실패하는 것입니다. 모호한 호출입니다.
어쨌든, SFINAE 규칙 때문에 오류가 삭제됩니다.
요청한대로 인수를 지정할 필요가 없습니다.
또한 proto
을 정의 할 필요는 없지만 반환 유형은 void
이어야합니다. 그렇지 않으면 다음과 같이 약간 decltype
에 전화를 수정해야합니다 : 당신이 예제 코드에서 볼 수 있듯이, static_assert
들 f
이 S
에 과부하가되어 있는지 확인
template<typename T>
constexpr bool has_single_f<T, decltype(proto(&T::f), void())> = true;
과는 U
에 있지 않습니다.
위 예제는 C++ 14 이후 언어의 일부인 템플릿 변수를 기반으로합니다. 당신이 C++ (11)와 함께 작동 잘 알려진 구조체 기반 솔루션을 선호하는 경우
, 당신은 다음과 같은 검출기 사용할 수 있습니다
#include<type_traits>
//...
template<typename, typename = void>
struct has_single_f: std::false_type {};
template<typename T>
struct has_single_f<T, decltype(proto(&T::f))>: std::true_type {};
//...
int main() {
static_assert(not has_single_f<S>::value, "!");
static_assert(has_single_f<U>::value, "!");
}
흥미로운 질문을, 그 할 수있는 방법을 찾을 재미 있었다. +1 – skypjack