【问题标题】:Is there any way to detect overloaded member function by name alone? (not to detect name)有没有办法仅通过名称来检测重载的成员函数? (不检测名字)
【发布时间】:2016-10-02 19:59:54
【问题描述】:

我在这里是一厢情愿,但我想准确地回答这个问题。我想改进仅通过名称来检测成员模板的实现,但我遇到了一个障碍。我找不到任何方法来检测重载的static/non-static 成员函数。这个问题的非常重要的部分是,我不能使用this trick,因为它检测到任何名称(我已经在当前的实现中使用它,有点用),我不能指定类型,因为那错过了单独使用名称的意义。

供参考,请参阅我的other question。我在那里发布了当前的has_member_template_bar 实现为an answer。我认为我不应该在这个问题中发布所有内容。

问题保持不变 - 我们可以检测重载的成员函数,而不指定它们的参数,或者使用提到的技巧吗?我知道我可能在要求不可能,但要求永远不会有坏处。

【问题讨论】:

  • 有趣的问题,找到一种方法很有趣。 +1

标签: c++ templates typetraits overloading member-functions


【解决方案1】:

问题保持不变 - 我们可以检测重载的成员函数,而不指定它们的参数,或者使用提到的技巧吗?我知道我可能要求的是不可能的,但要求永远不会有坏处

其实也不是不可能。
它遵循一个最小的工作示例:

template<typename T, typename R, typename... A>
void proto(R(T::*)(A...));

template<typename, typename = void>
constexpr bool has_single_f = false;

template<typename T>
constexpr bool has_single_f<T, decltype(proto(&T::f))> = true;

struct S {
    void f(int) {}
    void f(char) {}
};

struct U {
    void f() {}
};

int main() {
    static_assert(not has_single_f<S>, "!");
    static_assert(has_single_f<U>, "!");
}

当然,你需要添加更多的东西来区分成员方法和数据成员,但是添加它们是微不足道的(参见标题type_traits),我尽量让示例保持最小。

基本思想是,如果给定函数重载,则对proto 的调用会失败,因为这是一个模棱两可的调用
无论如何,由于 SFINAE 规则,错误被丢弃。
不需要按要求指定参数。
还要注意proto 不需要定义,但重要的是它的返回类型是void。否则,您必须稍微修改对decltype 的调用,如下所示:

template<typename T>
constexpr bool has_single_f<T, decltype(proto(&T::f), void())> = true;

从示例代码中可以看出,static_asserts 验证 fS 中被重载,并且不在 U 中。


上面的例子是基于模板变量,自 C++14 以来它是语言的一部分。
如果您更喜欢与 C++11 一起使用的众所周知的基于结构的解决方案,您可以使用以下检测器:

#include<type_traits>

//...

template<typename, typename = void>
struct has_single_f: std::false_type {};

template<typename T>
struct has_single_f<T, decltype(proto(&T::f))>: std::true_type {};

//...

int main() {
    static_assert(not has_single_f<S>::value, "!");
    static_assert(has_single_f<U>::value, "!");
}

【讨论】:

  • 我开始觉得模板没有什么是不可能的:)。很好的答案!
猜你喜欢
  • 2021-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多