如何检查类型是否存在无参数运算符()
我试图检查函子是否与给定的一组参数类型和给定的返回类型兼容(也就是说,给定的参数类型可以隐式转换为实际的参数类型,而返回类型则相反)。目前我使用以下代码:
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
这在大多数情况下工作得很好,但是当我测试像 struct foo{ int operator()() const;}; 这样的无参数函子时,它无法编译,因为在这种情况下,两个基类的 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_complete 的部分特化,在其中检查 &T::operator()
的类型是否是无参数成员函数,这更有效或更少。然而,当测试函子有多个operator()
时,这种方法显然会失败。
因此,我的问题是是否有更好的方法来测试无参数 operator()
是否存在以及如何执行。
I'm trying to check whether a functor is compatible with a given set of parametertypes and a given return type (that is, the given parametertypes can be implicitely converted to the actual parametertypes and the other way around for the return type). Currently I use the following code for this:
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>
This works quite nicely in the majority of cases, however it fails to compile when I'm testing parameterless functors like struct foo{ int operator()() const;};
, beccause in that case the two operator()
of base are apperently ambigous, leading to something like this:
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
So obvoiusly I need a different way to check this for parameterless functors. I tried making a partial specialization of is_functor_compatible
for an empty parameterpack, where I check if the type of &T::operator()
is a parameterless memberfunction, which works more or less. However this approach obviously fails when the tested functor has several operator()
.
Therefore my question is if there is a better way to test for the existence of a parameterless operator()
and how to do it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当我想测试给定表达式对于某种类型是否有效时,我使用与此类似的结构:
When I want to test if a given expression is valid for a type, I use a structure similar to this one:
您是否尝试过类似的操作:
之后,您区分了返回类型
hasFunctionCallOper((T*)0, 0)
。编辑(感谢 R. Martinho Fernandes 的建议):
这是有效的代码:
Have you tried something like:
After, you discriminate on the return type of
hasFunctionCallOper((T*)0, 0)
.EDITED (thanks to the suggestion of R. Martinho Fernandes):
Here's the code that works: