gpt4 book ai didi

c++ - 如何比较给定指针和类型的两个值

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:33:12 24 4
gpt4 key购买 nike

假设我有一个存储一些数据的类,

class Value {
public:
enum class Type {
int_type,
float_type,
double_type,
bool_type
};

friend bool operator==(const Value& lhs, const Value& rhs) {
// how to make this function clean and concise?
}

private:
void* ptr;
Type type;
};

ptr 指向基础值,type 指示应如何转换 ptr

要比较 Value 对象,我绝对可以列出所有可能的类型组合,但代码将难以维护。喜欢:

if (lhs.type == Type::int_type && rhs.type == Type::float_type) {
return *static_cast<int*>(lhs.ptr) == *static_cast<float*>(rhs.type);
}

知道如何降低复杂性吗?

更新:

我希望此类是动态类型,这意味着我可以执行以下操作:

Value v("abc");       // v is now a string
v = 123; // v is now an int
bool b = (v == 123.0); // b is true

所以我不认为模板有什么用。

最佳答案

实际上,您要做的是编写一个弱类型。

此类类型支持脚本语言,例如 python 和 javascript。

编写这样的类型比您最初想象的要复杂。

但是,一旦您定义了转换矩阵(例如,将字符串与 bool 值进行比较的规则是什么?)

这是一个开始,使用 std::variant:

#include <variant>
#include <string>
#include <type_traits>
#include <algorithm>
#include <cassert>

//
// Step 1 - define your conversion rules
// this is not as trivial as you might think
//

template<class To>
struct convert;

template<>
struct convert<int>
{
template<class From>
auto operator()(From const& from) const -> int
{
return int(from);
}
auto operator()(std::string const& from) const -> int
{
return std::atoi(from.c_str());
}
};
template<>
struct convert<double>
{
template<class From>
auto operator()(From const& from) const -> double
{
return double(from);
}
auto operator()(std::string const& from) const -> double
{
return std::atof(from.c_str());
}
};
template<>
struct convert<bool>
{
template<class From>
auto operator()(From const& from) const -> bool
{
return bool(from);
}
auto operator()(std::string from) const -> bool
{
auto lcase = [](auto ch) { return std::tolower(ch); };
std::transform(from.begin(), from.end(), from.begin(), lcase);
if (from == "true" || from == "yes" || std::atoi(from.c_str()))
return true;
else
return false;
}
};
template<>
struct convert<std::string>
{
template<class From>
auto operator()(From const& from) const -> std::string
{
return std::to_string(from);
}

auto operator()(bool const& from) const -> std::string
{
auto result = std::string();
if (from)
result.assign("true");
else
result.assign("false");
return result;
}

auto operator()(std::string const& from) const -> std::string const&
{
return from;
}
};

//
// Step 2 - use a std::variant
//

struct Value
{
explicit Value(int arg): store_(arg) {}
explicit Value(double arg): store_(arg) {}
explicit Value(bool arg): store_(arg) {}
explicit Value(std::string arg): store_(std::move(arg)) {}
explicit Value(const char* arg): store_(std::string(arg)) {}

friend bool operator==(const Value& lhs, const Value& rhs)
{
auto compare = [](auto &&l , auto&& r)
{
using l_type = std::decay_t<decltype(l)>;
auto conv = convert<l_type>();
return l == conv(r);
};
return std::visit(compare, lhs.store_, rhs.store_);
}

private:
using storage_type = std::variant<int, double, bool, std::string>;

private:
storage_type store_;
};

int main()
{
auto vt = Value(true);
auto vst = Value("true");
assert(vt == vst);
}

关于c++ - 如何比较给定指针和类型的两个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55660108/

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