gpt4 book ai didi

c++ - 如何检查 std::variant 是否可以保存某种类型

转载 作者:IT老高 更新时间:2023-10-28 22:13:49 25 4
gpt4 key购买 nike

我有一个包含 std::variant 的类。这个 std::variant 类型只允许保存一个特定的类型列表。

我有模板函数,它允许类的用户将各种值插入到 std::unordered_map 中,映射包含这种变体类型的值。即,仅当其类型在特定类型列表中时,才允许用户插入值。但是,我不希望用户自己定义这个类型列表。

class GLCapabilities
{
public:
using VariantType = std::variant<GLint64>; // in future this would have other types

template <typename T>
std::enable_if_t<???> AddCapability(const GLenum parameterName)
{
if(m_capabilities.count(parameterName) == 0)
{
/*... get correct value of type T ... */
m_capabilities.insert(parameterName,value);
}
}

template<typename T>
std::enable_if_t<???,T> GetCapability(const GLenum parameterName) const
{
auto itr = m_capabilities.find(parameterName);
if(std::holds_alternative<T>(*itr))
return std::get<T>(*itr);

return T;
}

private:
std::unordered_map<GLenum,VariantType> m_capabilities;
};

您会在上面看到???,我该如何检查? std::disjunctionstd::is_same 的某种组合?

喜欢

std::enable_if<std::disjunction<std::is_same<T,/*Variant Types???*/>...>>

为了清楚起见,我宁愿不必手动检查每个允许的类型。

最佳答案

编辑:我真的很喜欢你的std::disjunction想法,它绝对有效。您只需使用模板特化提取类型列表。

我的整个老式递归困惑变得简单:

template<typename T, typename VARIANT_T>
struct isVariantMember;

template<typename T, typename... ALL_T>
struct isVariantMember<T, std::variant<ALL_T...>>
: public std::disjunction<std::is_same<T, ALL_T>...> {};

原始答案:这是一个完成此任务的简单模板。它通过返回 false 来工作对于空类型列表。对于非空列表,它返回 true如果第一种类型通过 std::is_same<> , 并以除第一个类型以外的所有类型递归调用自身。

#include <vector>
#include <tuple>
#include <variant>

// Main lookup logic of looking up a type in a list.
template<typename T, typename... ALL_T>
struct isOneOf : public std::false_type {};

template<typename T, typename FRONT_T, typename... REST_T>
struct isOneOf<T, FRONT_T, REST_T...> : public
std::conditional<
std::is_same<T, FRONT_T>::value,
std::true_type,
isOneOf<T, REST_T...>
>::type {};

// Convenience wrapper for std::variant<>.
template<typename T, typename VARIANT_T>
struct isVariantMember;

template<typename T, typename... ALL_T>
struct isVariantMember<T, std::variant<ALL_T...>> : public isOneOf<T, ALL_T...> {};

// Example:
int main() {
using var_t = std::variant<int, float>;

bool x = isVariantMember<int, var_t>::value; // x == true
bool y = isVariantMember<double, var_t>::value; // y == false

return 0;
}

注意确保在调用它之前从 T 中剥离 cv 和引用限定符(或将剥离添加到模板本身)。真的,这取决于您的需求。

关于c++ - 如何检查 std::variant 是否可以保存某种类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45892170/

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