gpt4 book ai didi

c++ - 如果对象用作左值或右值,如何检测和处理?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:25:22 26 4
gpt4 key购买 nike

我有一个名为 Properties 的容器类。我想向其中添加 operator[](const std::string & name) ,它将返回具有指定名称的属性。

现在让我们考虑没有指定名称的属性。在这种情况下,如果它用作左值,我不想将具有指定名称的新 Property 添加到我的 Properties 中,否则抛出异常。

Properties pts;
pts.add("name1", val1);
pts.add("name2", val2);
pts["name1"] = val3; //OK
pts["name3"] = val1; //OK creating new Property with value = val1
cout << pts["name4"]; //Ooops can't find Property with name = "name4", so throwing an exception

这在 C++ 中可行吗?我怎样才能写出这样的operator[]

最佳答案

您可以覆盖您给出的案例,但不能通过实际检查是否发生左值到右值的转换来覆盖。我认为不可能直接拦截它,因此您需要改为引发不同的转换:

  • operator[] 返回一个代理对象,正如 John Zwinck 所说。仅创建此代理对象并不会创建 key 。

  • 代理对象有一个operator=(const V&),因此它通过创建键来处理赋值。或者,您也可以使用 operator+=operator++ 和其他 - 我不确定您的意思是 any 左值使用是否正常,或者直接分配。

  • 代理对象有一个到 V& 的转换,如果键尚不存在则抛出。

编辑:这似乎模糊地工作,尽管有它没有涵盖的用例,例如将 operator[] 的返回值传递给接受 V&< 的函数 并在那里分配给它。此外,隐藏代理+转换永远不会产生与原始类型完全等效的接口(interface),因为隐式转换最多涉及一个用户定义的转换,并且代理“用完”该转换。

#include <iostream>
#include <map>
#include <string>
#include <stdexcept>

struct FunnyMap;

struct ProxyValue {
FunnyMap *ptr;
std::string key;
ProxyValue(const std::string &key, FunnyMap *ptr) : ptr(ptr), key(key) {}
operator int&();
int &operator=(int i);
};

struct FunnyMap {
std::map<std::string, int> values;
ProxyValue operator[](const std::string &key) {
return ProxyValue(key, this);
}
};

ProxyValue::operator int&() {
if (ptr->values.count(key) != 0) {
return ptr->values[key];
} else {
throw std::runtime_error("no key");
}
}

int &ProxyValue::operator=(int i) {
return ptr->values[key] = i;
}

void foo(int &i) {
i = 4;
}

int main() {
try {
FunnyMap f;
f["foo"] = 1;
std::cout << f["foo"] << "\n";
std::cout << f["bar"];
// foo(f["bar"]); // also throws
} catch (const std::exception &e) {
std::cout << "Exception: " << e.what() << "\n";
}
}

输出:

1
Exception: no key

关于c++ - 如果对象用作左值或右值,如何检测和处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5770760/

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