我在这里如意,但我想确切地说明这个问题。我想通过他们的名字来改进检测成员模板的实现,但我遇到了一个障碍。我找不到任何方法来检测重载的static
/非 - static
成员函数。这个问题的一个非常重要的部分是,我不能使用this trick,因为它检测到任何名称(我已经在当前实现中使用它,有点有用),并且我无法指定类型,因为错过了单独使用名称的观点。
供参考,请参阅我的other question。我在那里发布了当前has_member_template_bar
实施an answer。我不认为我应该在这个问题上发布所有内容。
问题保持不变 - 我们可以检测重载的成员函数,而无需指定其参数或使用提到的技巧吗?我知道我可能要求不可能,但问问题永远不会伤害。
答案 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, "!");
}