首先,您需要声明A为完整类型(例如,A<int>
)。
这不是relyable检查对象是否invokeable或不只是通过展开,并比较它的operator()
,因为它会在模板或重载函数子失败。
林using the following piece of code 以检测对象是否是可调用与给定的函数签名(ReturnType(Arguments...)
)
这工作也可用于过载或模板operator()
的,因为代码试图具有给定参数 代替调用该对象比较其解开的签名operator()
。
作为小的添加,如果对象可以从const,volatile或rvalue上下文中调用,也可以检查该对象。
#include <type_traits>
template<typename Fn>
struct impl_is_callable_with_qualifiers;
template<typename ReturnType, typename... Args>
struct impl_is_callable_with_qualifiers<ReturnType(Args...)>
{
template<typename T>
static auto test(int)
-> typename std::is_convertible<
decltype(std::declval<T>()(std::declval<Args>()...)),
ReturnType
>;
template<typename T>
static auto test(...)
-> std::false_type;
};
template<bool Condition, typename T>
using add_const_if_t = typename std::conditional<
Condition,
typename std::add_const<T>::type,
T
>::type;
template<bool Condition, typename T>
using add_volatile_if_t = typename std::conditional<
Condition,
typename std::add_volatile<T>::type,
T
>::type;
template<bool Condition, typename T>
using add_lvalue_if_t = typename std::conditional<
Condition,
typename std::add_lvalue_reference<T>::type,
T
>::type;
template<typename T, typename Fn, bool Const, bool Volatile, bool RValue>
using is_callable_with_qualifiers = decltype(impl_is_callable_with_qualifiers<Fn>::template test<
add_lvalue_if_t<!RValue,
add_volatile_if_t<Volatile,
add_const_if_t<Const,
typename std::decay<T>::type>>>
>(0));
这是不可能确定一个类型是否有超载operator()
, 的任何变体,但是你可以测试特定类型或执行多种类型的测试,以检测“可能”的模板。
覆盖从你的问题的代码将是一个例子:
#include <iostream>
template<typename T>
class A
{
public:
A() = default;
T operator()() { return T(); }
T operator()(T a) { return T(); }
T operator()(T a, T b) { return T(); }
};
template <typename TheClass, typename T>
using is_callable = is_callable_with_qualifiers<TheClass, T(T), false, false, false>;
int main()
{
std::cout << is_callable<A<int>, int>::value; // true
}
Demo
你打算如何使用这些信息?在大多数情况下,您实际上并不关心它是否可以调用,您只关心它是否可以用想要传递给它的特定参数进行调用,并且这已经很容易检测到。 – hvd
我问的原因是因为这是不可能的,但取决于你具体做了什么,以及你可以对将要测试的类型做出什么假设,还有其他可能。如果你会检查我的答案历史记录,你会看到我回答C++问题,包括有关使用模板来检测类型特征的问题。但如果你更高兴地认为我会破坏你的经验,那就去吧,我不希望被指责试图控制你的想法。 – hvd
我也很好奇所需的用例。充其量,我可以写一些东西来检查一个类型是否可以用最多N个参数进行调用,并且对这些参数最终会产生什么限制。 – Barry