有没有办法单独通过名称检测重载的成员函数? (不是为了检测姓名)

时间:2016-10-02 19:59:55

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

我在这里如意,但我想确切地说明这个问题。我想通过他们的名字来改进检测成员模板的实现,但我遇到了一个障碍。我找不到任何方法来检测重载的static /非 - static成员函数。这个问题的一个非常重要的部分是,我不能使用this trick,因为它检测到任何名称(我已经在当前实现中使用它,有点有用),并且我无法指定类型,因为错过了单独使用名称的观点。

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

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

1 个答案:

答案 0 :(得分: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_assert验证f中的S已超载且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, "!");
}