如何检查类型是否存在无参数操作符()
Howto check a type for the existence of parameterless operator()
我试图检查一个函子是否与给定的一组参数类型和给定的返回类型兼容(也就是说,给定的参数类型可以隐式地转换为实际的参数类型,而返回类型则相反)。目前我使用以下代码:
template<typename T, typename R, template<typename U, typename V> class Comparer>
struct check_type
{ enum {value = Comparer<T, R>::value}; };
template<typename T, typename Return, typename... Args>
struct is_functor_compatible
{
struct base: public T
{
using T::operator();
std::false_type operator()(...)const;
};
enum {value = check_type<decltype(std::declval<base>()(std::declval<Args>()...)), Return, std::is_convertible>::value};
};
check_type<T, V, Comparer>
这在大多数情况下工作得很好,但是当我测试像struct foo{ int operator()() const;};
这样的无参数函子时,它无法编译,因为在这种情况下,base的两个operator()
显然是含糊不清的,导致如下所示:
error: call of '(is_functor_compatible<foo, void>::base) ()' is ambiguous
note: candidates are:
note: std::false_type is_functor_compatible<T, Return, Args>::base::operator()(...) const [with T = foo, Return = void, Args = {}, std::false_type = std::integral_constant<bool, false>]
note: int foo::operator()() const
显然我需要一种不同的方法来检查无参数函子。我尝试为空参数包对is_functor_compatible
进行部分专门化,在那里我检查&T::operator()
的类型是否为无参数成员函数,它或多或少地起作用。然而,当测试函子有多个operator()
时,这种方法显然失败了。
因此,我的问题是是否有更好的方法来测试无参数operator()
的存在以及如何做到这一点。
当我想测试给定表达式是否对某个类型有效时,我使用类似于下面的结构:
template <typename T>
struct is_callable_without_parameters {
private:
template <typename T1>
static decltype(std::declval<T1>()(), void(), 0) test(int);
template <typename>
static void test(...);
public:
enum { value = !std::is_void<decltype(test<T>(0))>::value };
};
您试过这样做吗:
template<size_t>
class Discrim
{
};
template<typename T>
std::true_type hasFunctionCallOper( T*, Discrim<sizeof(T()())>* );
template<typename T>
std::false_type hasFunctionCallOper( T*, ... );
之后,对返回类型进行区分hasFunctionCallOper((T*)0, 0)
.
编辑(感谢R. Martinho Fernandes的建议):
下面是有效的代码:
template<size_t n>
class CallOpDiscrim {};
template<typename T>
TrueType hasCallOp( T*, CallOpDiscrim< sizeof( (*((T const*)0))(), 1 ) > const* );
template<typename T>
FalseType hasCallOp( T* ... );
template<typename T, bool hasCallOp>
class TestImpl;
template<typename T>
class TestImpl<T, false>
{
public:
void doTellIt() { std::cout << typeid(T).name() << " does not have operator()" << std::endl; }
};
template<typename T>
class TestImpl<T, true>
{
public:
void doTellIt() { std::cout << typeid(T).name() << " has operator()" << std::endl; }
};
template<typename T>
class Test : private TestImpl<T, sizeof(hasCallOp<T>(0, 0)) == sizeof(TrueType)>
{
public:
void tellIt() { this->doTellIt(); }
};
相关文章:
- 模板化检查是否存在带有参数列表的类成员函数?
- 构造函数 (C++) 中的 char 指针参数存在问题
- 为什么当函数参数未定义为常量引用时存在无限递归?
- C++20 概念 如何定义带有参数的函数的存在?
- 使用聚合初始化模拟默认函数参数是否存在任何陷阱?
- 在存在错误代码的情况下输出参数与 NRVO
- 如何检查运算符 != 模板参数是否存在 C++ 17?
- 在 mingw64-gcc 上可能存在可变参数的错误
- 当元组给出参数时,如何检查方法是否存在?
- 如果存在具有不同参数的继承成员,为什么对 C++ 结构函数的调用不明确?
- 哪个编译器(如果有的话)在参数包扩展中存在错误
- Clang和GCC在转换C++17中非类型模板参数的自动说明符中存在分歧
- 为什么与非类型参数相反,为什么不可见/存在模板类型参数
- 从返回函数中推断不存在的模板参数
- 错误:"参数"没有命名类型,.cpp和 .h 文件可能存在问题
- CUDA9.2及以上版本中模板默认参数存在无法解决的外部函数错误
- 在 c++ 中具有多个参数构造函数的模板类存在问题
- std::enable_if 基于可变参数模板的存在
- 不存在的标识符在非启用函数模板中用作默认参数
- 是否存在只返回其参数的std函数