您的代码中有几个问题:
-
您的operator== 中的const &T t 应为T const& t 或const T& t。
-
您忘记提及要与
std::string 不在 if 语句中使用 char 数组(即 "linear")。意思是你
需要以下任一项:
if (kwargs["interface"] == std::string{ "linear" })
// or
using namespace std::string_literals;
if (kwargs["interface"] == "linear"s) // since C++14
-
当你像这样进行比较时
if (kwargs["interface"] == "linear") // checking std::variant == char [7]
您正在检查std::variant<float, int, bool, std::string>(即v)类型为char [7](即linear 类型)。
当条件达到operator== 的定义时,您再次执行
同样的
return v == t; // checking std::variant == char [7]
这会导致对模板化 operator== 本身的递归调用
因此堆栈溢出。
为了修复,您需要strong text通过索引或类型明确指定变体中的值。例如,使用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;
}
或者简单地说(学分@Barry)
template<typename T>
bool operator==(const std::variant<float, int, bool, std::string>& v, T const& t)
{
return std::get<T>(v) == t;
}
现在,如果您传递除 v 包含之外的任何其他类型,您将收到模板化 operator== 的编译时错误。
通用解决方案!
对于通用std::varaint<Types...>,可以执行以下操作。此外,SFINAE 仅用于传递的 std::variant<Types> 中的那些类型。我用过is_one_of trait from this post。
(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;
}