[英]Provide a operator== for std::variant
I am trying to create an operator==
operator for an std::variant
defined in the map like this:我正在尝试为 map 中定义的
std::variant
创建一个operator==
运算符,如下所示:
struct anyType
{
template<typename T>
void operator()(T t) const { std::cout << t; }
void operator()(const std::string& s) const { std::cout << '\"' << s << '\"'; }
};
template<typename T>
bool operator==(const std::variant<float, int, bool, std::string>& v, const& T t)
{
return v == t;
}
int main()
{
std::map<std::string, std::variant<float, int, bool, std::string>> kwargs;
kwargs["interface"] = "linear"s;
kwargs["flag"] = true;
kwargs["height"] = 5;
kwargs["length"] = 6;
//test
if (kwarg["interface"] == "linear") // stack overflow Error here
{
std::cout << true << '\n';
}
else
{
std::cout << false << '\n';
}
}
Can someone tell me why my operator isn't working?有人能告诉我为什么我的接线员不工作吗?
You have a couple of issues in your code:您的代码中有几个问题:
const &T t
in your operator==
, should be T const& t
or const T& t
. operator==
中的const &T t
应该是T const& t
或const T& t
。
You have forgotten to mention that you want to compare with a std::string
not with char
array in your if statement(ie "linear"
).您忘记提及您想在 if 语句(即
"linear"
)中与std::string
而不是char
数组进行比较。 Meaning you need either of the followings:这意味着您需要以下任一项:
if (kwargs["interface"] == std::string{ "linear" }) // or using namespace std::string_literals; if (kwargs["interface"] == "linear"s) // since C++14
When you do the comparison like this当你像这样进行比较时
if (kwargs["interface"] == "linear") // checking std::variant == char [7]
You are checking the std::variant<float, int, bool, std::string>
(ie v
) with type char [7]
(ie type of linear
).您正在检查
char [7]
类型(即linear
类型)的std::variant<float, int, bool, std::string>
(即v
)。 When the condition reaches the operator==
's definition you do again the same by当条件达到
operator==
的定义时,您再次执行相同的操作
return v == t; // checking std::variant == char [7]
This leads to a recursive call to the templated operator==
itself and hence stack overflow.这会导致对模板化
operator==
本身的递归调用,从而导致堆栈溢出。
In order to fix, you need strong text to explicitly specify the value from the variant either by index or by type.为了修复,您需要强文本以通过索引或类型显式指定变体中的值。 For example, chacking the type using
std::is_same
and if constexpr
:例如,使用
std::is_same
和if constexpr
来检查类型:
( See live online ) (见在线直播)
#include <type_traits> std::is_same_v
template<typename T>
bool operator==(const std::variant<float, int, bool, std::string>& v, T const& t)
{
if constexpr (std::is_same_v<T, float>) // float
return std::get<float>(v) == t;
else if constexpr (std::is_same_v<T, int>) // int
return std::get<int>(v) == t;
else if constexpr (std::is_same_v<T, bool>) // boolean
return std::get<bool>(v) == t;
else if constexpr (std::is_same_v<T, std::string>) // std::string
return std::get<std::string>(v) == t;
}
or simply ( Credits @Barry )或者干脆(学分@Barry )
template<typename T>
bool operator==(const std::variant<float, int, bool, std::string>& v, T const& t)
{
return std::get<T>(v) == t;
}
Now if you pass any other types other than v
contains, you will get a compile-time error for the templated operator==
.现在,如果您传递
v
contains 以外的任何其他类型,您将收到模板化operator==
的编译时错误。
For a generic std::varaint<Types...>
, one can do as follows.对于通用
std::varaint<Types...>
,可以执行以下操作。 In addition, it has been SFINAE d for only those types which are in the passed std::variant<Types>
.此外,仅对传递的
std::variant<Types>
中的那些类型进行了SFINAE d。 I have used the is_one_of
trait from this post .我使用了这篇文章中的
is_one_of
特征。
( See Live Online ) (见在线直播)
#include <variant>
#include <type_traits>
// A trait to check that T is one of 'Types...'
template <typename T, typename...Types>
struct is_one_of final : std::disjunction<std::is_same<T, Types>...> {};
template<typename... Types, typename T>
auto operator==(const std::variant<Types...>& v, T const& t) noexcept
-> std::enable_if_t<is_one_of<T, Types...>::value, bool>
{
return std::get<T>(v) == t;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.