사용자가 함수 포인터을 매개 변수로 전달한 경우 특정 템플릿을 사용하려면 SFINAE를 사용하고 싶습니다.`std :: enable_if`는 함수 포인터입니다 - 어떻게?
나는 봤지만 아무 것도 발견하지 못했습니다. 또한 <type_traits>
설명서를 보았지만 is_function_ptr<T>
과 비슷한 것을 찾을 수 없었습니다.
함수 포인터는 TReturn(*)(TArgs...)
과 같은 전역 함수 포인터를 의미합니다.
사용자가 함수 포인터을 매개 변수로 전달한 경우 특정 템플릿을 사용하려면 SFINAE를 사용하고 싶습니다.`std :: enable_if`는 함수 포인터입니다 - 어떻게?
나는 봤지만 아무 것도 발견하지 못했습니다. 또한 <type_traits>
설명서를 보았지만 is_function_ptr<T>
과 비슷한 것을 찾을 수 없었습니다.
함수 포인터는 TReturn(*)(TArgs...)
과 같은 전역 함수 포인터를 의미합니다.
다음은 기능 포인터와 몇 가지 테스트 케이스가 있는지 판별하는 유형 특성입니다. 함수 포인터인지 여부를 테스트하려면 std::is_pointer<P>::value
이 true
이고 std::is_function<T>::value
이 true
인 경우 T
이 P
이고 포인터를 제거했는지 테스트해야합니다. 아래 코드는 그 일을합니다 :
#include <type_traits>
#include <iostream>
#include <utility>
template <typename Fun>
struct is_fun_ptr
: std::integral_constant<bool, std::is_pointer<Fun>::value
&& std::is_function<
typename std::remove_pointer<Fun>::type
>::value>
{
};
template <typename Fun>
typename std::enable_if<is_fun_ptr<Fun>::value>::type
test(Fun) {
std::cout << "is a function pointer\n";
}
template <typename Fun>
typename std::enable_if<!is_fun_ptr<Fun>::value>::type
test(Fun) {
std::cout << "is not a function pointer\n";
}
void f0() {}
void f1(int) {}
void f2(int, double) {}
struct s0 { void operator()() {} };
struct s1 { void operator()(int) {} };
struct s2 { void operator()(int, double) {} };
int main()
{
int v0(0);
int* p0(&v0);
void (*p1)() = &f0;
void (**p2)() = &p1;
std::cout << "v0="; test(v0);
std::cout << "p0="; test(p0);
std::cout << "p1="; test(p1);
std::cout << "p2="; test(p2);
std::cout << "f0="; test(&f0);
std::cout << "f1="; test(&f1);
std::cout << "f2="; test(&f2);
std::cout << "s0="; test(s0());
std::cout << "s1="; test(s1());
std::cout << "s2="; test(s2());
std::cout << "l0="; test([](){});
std::cout << "l1="; test([](int){});
std::cout << "l2="; test([](int, double){});
}
'constexpr' 함수 템플릿과 nm의 대답 에서처럼 쉽게 특성을 만들 수 있습니까? 그리고 그것은 훨씬 더 강력합니다 (매개 변수의 최소 수 또는 특정 반환 유형을 요구할 수 있음). –
@BenVoigt : 예. 그러나 질문은 "n.m. 솔루션에 기반한 함수 포인터가있는 경우 어떻게 감지 할 수 있습니까?"또는 최소 인수 수 또는 특정 반환 유형에 대한 질문이 없었습니다. –
그렇습니다. 그러나'enable_if'는 형질이'remove_pointer'를 통해 만들어 지거나 직접 구현되었는지 상관하지 않습니다. –
함수 포인터 나 멤버 함수 포인터를 받아들이는 데는 SFINAE가 필요하지 않습니다. 함수 객체를 호출 불가능한 객체와 구별하려면 SFINAE가 필요합니다.이 문제를 해결할 방법은 없습니다.
#include <utility>
#include <iostream>
template <typename Ret, typename... Parm>
void moo (Ret (*fp)(Parm...))
{
std::cout << "funptr" << std::endl;
}
template <typename Ret, typename Owner, typename... Parm>
void moo (Ret (Owner::*fp1)(Parm...))
{
std::cout << "memfunptr" << std::endl;
}
template <typename Funobj, typename... Parm,
typename Ret =
decltype((std::declval<Funobj>())
(std::forward(std::declval<Parm>())...))>
void moo (Funobj functor)
{
std::cout << "funobj" << std::endl;
}
void x1() {}
struct X2 { void x2() {} };
struct X3 { void operator()(){} };
int main()
{
moo(x1);
moo(&X2::x2);
moo(X3());
}
is_function과 is_pointer를 모두 확인할 수 있습니까? –
왜 SFINAE인가? 여기에는 과도한 행동이 있습니다. –
왜 간단한 f (std :: function)가 필요하지 않습니까? –