gpt4 book ai didi

C++17如何测试类是否有成员变量?

转载 作者:行者123 更新时间:2023-12-03 11:15:03 29 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





How to detect whether there is a specific member variable in class?

(10 个回答)


10 个月前关闭。




我沿着路线走

struct S {
static constexpr int extra=5;
};

struct V {
};


template <typename T>
void f()
{
if (std::is_same_v<decltype(T::extra), int>)
std::cout<< "extra exists" <<std::endl;
}
但是打电话 f<S>()失败为
std::is_same_v<decltype(S::extra), int> == 0
f<V>()不编译

最佳答案

如果您被困在 ,您可以添加一些基础设施,以便更轻松地进行此类检测。
检测成语
检测此类特征的最可重用/一致的方法是通过 Detection idiom ,它通过 std::void_t 利用 SFINAE在模板中。
这可以逐字取自 std::experimental::is_detected 来自 cppreference 的页面。这有效地为 C++17 提供了以类似于 C++20 概念的方式检测特征的能力;并且基础设施可以很容易地重用于任何检测。
您需要的基础知识是:

#include <type_traits>

namespace detail {
template <class Default, class AlwaysVoid,
template<class...> class Op, class... Args>
struct detector {
using value_t = std::false_type;
using type = Default;
};

template <class Default, template<class...> class Op, class... Args>
struct detector<Default, std::void_t<Op<Args...>>, Op, Args...> {
using value_t = std::true_type;
using type = Op<Args...>;
};

} // namespace detail

struct nonesuch{};

template <template<class...> class Op, class... Args>
using is_detected = typename detail::detector<nonesuch, void, Op, Args...>::value_t;
注:上述基础设施可以重复用于任何检测。它是 C++17 中非常有用的可重用工具。
is_detected ,您只需要一个检测器,它只是一个模板别名,计算结果为 decltype表达可能存在或不存在的事物。
所以在你的情况下,有条件地检测 T::extra 的存在,你可以用一个简单的检测器来做到这一点,比如:
template <typename T>
using detect_extra = decltype(T::extra);
现在把它们放在一起,你可以使用这个检测器有条件地切换分支:
if constexpr (is_detected<detect_extra,T>::value) {
// Only do code if 'T' has 'T::extra' (e.g. 'S')
} else {
// Only do code if 'T' does not have 'T::extra' (e.g. 'V')
}
Live Example

如果到特定类型的等效转换很重要,例如 extra需要可转换为 int ,您也可以使用 is_detected_convertible 并使用检测器检查结果是否可以转换为所需的类型。再次使用相同的 cppreference 页面,您可以定义 is_detected_convertible作为:
template <template<class...> class Op, class... Args>
using detected_t = typename detail::detector<nonesuch, void, Op, Args...>::type;

template <class To, template<class...> class Op, class... Args>
using is_detected_convertible = std::is_convertible<detected_t<Op, Args...>, To>;
这允许检查改为:
if constexpr (is_detected_convertible<int, detect_extra, T>::value) {
// Only do code if 'T' has 'T::extra' convertible to int (e.g. 'S')
} else {
// Only do code if 'T' does not have 'T::extra', or is not int
}
Live Example
概念(仅限 C++20+)
如果您有权访问 及以后, concept s 让这变得更简单——因为你可以简单地使用 concept + requires条款如:
#include <concepts> // std::same_as

template <typename T>
concept HasExtra = requires(T) {
{T::extra} -> std::same_as<int>;
};

if constexpr (HasExtra<T>) {
// Only do code if 'T' has 'T::extra' and is 'int' (e.g. 'S')
} else {
// Only do code if 'T' does not have 'T::extra' (e.g. 'V')
}
Live Example

关于C++17如何测试类是否有成员变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66078754/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com