为什么 SFINAE 不起作用?
Why SFINAE doesn't work?
我想检查 class 是否有 operator()。
我尝试了以下 SFINAE。
#include <type_traits> //for std::true_type/false_type
#include <utility> //for std::declval
template <typename T, typename... A>
class has_call_operator {
private:
template <typename U, typename... P>
static auto check(U u, P... p) -> decltype(u(p...), std::true_type());
static auto check(...) -> decltype(std::false_type());
public:
using type
= decltype(check(std::declval<T>(), std::declval<A>()...));
static constexpr bool value = type::value;
};
乍一看,这是正确的。
#include <iostream>
struct test {
void operator()(const int x) {}
};
int main()
{
std::cout << std::boolalpha << has_call_operator<test, int>::value << std::endl; //true
return 0;
}
但是,摘要 class 没有被它正确地处理。
#include <iostream>
struct test {
void operator()(const int x) {}
virtual void do_something() = 0;
};
int main()
{
std::cout << std::boolalpha << has_call_operator<test, int>::value << std::endl; //false
return 0;
}
为什么这段代码不起作用?
另外,你能让这段代码起作用吗?
你按值取U
,所以它也需要构造类型。
通过 const 引用来解决这个问题。
您可能会查看 并得到类似的内容:
template <typename T, typename ...Ts>
using call_operator_type = decltype(std::declval<T>()(std::declval<Ts>()...));
template <typename T, typename ... Args>
using has_call_operator = is_detected<call_operator_type, T, Args...>;
我想检查 class 是否有 operator()。 我尝试了以下 SFINAE。
#include <type_traits> //for std::true_type/false_type
#include <utility> //for std::declval
template <typename T, typename... A>
class has_call_operator {
private:
template <typename U, typename... P>
static auto check(U u, P... p) -> decltype(u(p...), std::true_type());
static auto check(...) -> decltype(std::false_type());
public:
using type
= decltype(check(std::declval<T>(), std::declval<A>()...));
static constexpr bool value = type::value;
};
乍一看,这是正确的。
#include <iostream>
struct test {
void operator()(const int x) {}
};
int main()
{
std::cout << std::boolalpha << has_call_operator<test, int>::value << std::endl; //true
return 0;
}
但是,摘要 class 没有被它正确地处理。
#include <iostream>
struct test {
void operator()(const int x) {}
virtual void do_something() = 0;
};
int main()
{
std::cout << std::boolalpha << has_call_operator<test, int>::value << std::endl; //false
return 0;
}
为什么这段代码不起作用? 另外,你能让这段代码起作用吗?
你按值取U
,所以它也需要构造类型。
通过 const 引用来解决这个问题。
您可能会查看
template <typename T, typename ...Ts>
using call_operator_type = decltype(std::declval<T>()(std::declval<Ts>()...));
template <typename T, typename ... Args>
using has_call_operator = is_detected<call_operator_type, T, Args...>;