输入特征以检查类是否具有成员函数

编程入门 行业动态 更新时间:2024-10-23 07:30:50
本文介绍了输入特征以检查类是否具有成员函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

尝试创建一种方法来识别给定的类是否具有可以调用的给定函数,并返回某种类型。

Trying to create a way to identify if a given class has a given function that can be invoked, and returns some type.

对我所要表达的任何想法这里做错了吗?

Any idea on what I'm doing wrong here? Is there a better way to determine if a given method is invoke'able given a class?

#include <string> #include <type_traits> #define GENERATE_HAS_MEMBER_FUNC(func, rettype) \ template<typename T, class Enable = void> struct has_##func; \ template<typename T, class U> struct has_##func : std::false_type {}; \ template<typename T> \ struct has_##func<T, \ typename std::enable_if<std::is_same< \ typename std::result_of<decltype (&T::func)(T)>::type, \ rettype>::value>::type> : std::true_type{}; \ template<class T> constexpr bool has_##func##_v = has_##func<T>::value; GENERATE_HAS_MEMBER_FUNC(str, std::string) GENERATE_HAS_MEMBER_FUNC(str2, std::string) GENERATE_HAS_MEMBER_FUNC(funca, std::string) GENERATE_HAS_MEMBER_FUNC(strK, std::string) GENERATE_HAS_MEMBER_FUNC(fancy, std::string) GENERATE_HAS_MEMBER_FUNC(really, std::string) struct A1 { virtual std::string str() const { return ""; } std::string strK() const { return ""; } virtual std::string fancy()=0; }; struct A2 : A1 { std::string str() const override { return ""; } std::string funca(); std::string fancy() override { return ""; } std::string really(int a=0) const { return std::to_string(a); } }; int main() { static_assert(has_str_v<A1>, "A1::str is virtual method with impl on base"); // MSVC: NO, clang: OK, GCC: NO static_assert(has_strK_v<A1>, "A1::strK is implemented inline "); // MSVC: NO, clang: OK, GCC: NO static_assert(has_fancy_v<A1>, "A1::fancy is a pure virtual method on base"); // MSVC: NO, clang: OK, GCC: NO static_assert(!has_really_v<A1>, "A1::really doesn't exist in A1"); // MSVC: OK, clang: OK, GCC: OK static_assert(has_str_v<A2>, "A2::str is override method "); // MSVC: OK, clang: OK, GCC: OK static_assert(!has_str2_v<A2>, "A2::str2 does not exist in A2"); // MSVC: NO, clang: OK, GCC: OK static_assert(has_funca_v<A2>, "A2::funca is defined (no impl) in A2"); // MSVC: OK, clang: OK, GCC: OK static_assert(has_strK_v<A2>, "A2::strK is implemented method on base"); // MSVC: OK, clang: OK, GCC: OK static_assert(has_fancy_v<A2>, "A1::fancy is a override of pure virtual method of base"); // MSVC: OK, clang: OK, GCC: OK static_assert(has_really_v<A2>, "A2::really has default param (can be invoked without params)"); // MSVC: OK, clang: NO, GCC: NO return 0; }

此实现有些令人惊讶。

Some surprises on this implementation.

编辑:在尝试实现@ Jarod42和@Vittorio Romeo时,提出了很棒的建议:

Upon trying to implement @Jarod42 and @Vittorio Romeo awesome suggestions:

#define GENERATE_HAS_MEMBER_FUNC(func, rettype) \ template<class T> using _has_##func_chk = \ decltype(std::declval<T &>().func()); \ template<class T> constexpr bool has_##func##_v = \ is_detected_exact_v<rettype, _has_##func_chk, T>;

现在VS2015上有两个测试用例仍然失败(没有任何意义): static_assert(!has_really_v, A1 :: really在A1中不存在); static_assert(!has_str2_v, A2 :: str2在A2中不存在);

now two test cases still fail on VS2015 (doesn't make any sense): static_assert(!has_really_v, "A1::really doesn't exist in A1"); static_assert(!has_str2_v, "A2::str2 does not exist in A2");

我可能缺少一些愚蠢的东西。

there is probably something silly something that I'm missing... any clues?

推荐答案

有没有更好的方法来确定给定方法是否被调用?能给定一堂课吗?

Is there a better way to determine if a given method is invoke'able given a class?

是的,您可以使用 检测习惯用法 ,可以在C ++ 11 中实现(链接页面包含有效的实现)。

下面是一个例子: Cat 是否有 float Cat :: purr (int)方法?

Here's an example: does Cat have a float Cat::purr(int) method?

struct Cat { float purr(int){} }; template<class T> using has_purr = decltype(std::declval<T&>().purr(std::declval<int>())); static_assert(std::experimental::is_detected_exact_v<float, has_purr, Cat>);

wandbox示例

必需的检测习惯用法 C ++ 17依赖关系在C ++ 11中很容易实现:

The required detection idiom C++17 dependencies are trivial to implement in C++11:

template< class... > using void_t = void; struct nonesuch { nonesuch() = delete; ~nonesuch() = delete; nonesuch(nonesuch const&) = delete; void operator=(nonesuch const&) = delete; };

这是 魔盒上完全符合C ++ 11的最小示例 。

更多推荐

输入特征以检查类是否具有成员函数

本文发布于:2023-11-11 07:49:46,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1577798.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:函数   特征   成员

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!