- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个名为 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/
我是 C++ 的新手,正在尝试编写如下接口(interface): template class Comparable { protected: Comparable(){};
什么是左值? 最佳答案 左值是可以分配给以下值的值: lvalue = rvalue; 它是“left value”或“lefthand value”的缩写,它基本上只是=符号左侧的值,即您为其分配值
这个问题已经有答案了: Why do C and C++ support memberwise assignment of arrays within structs, but not general
C++03 $14.1/6 - "A non-type non-reference template-parameter is not an lvalue." C++0x $14.2/6- "A no
这只是出于好奇我问... 我在任何地方看到的 99% 的代码,当使用“IF”时,将采用“If (RValue == LValue) ...”格式。例子: If (variableABC == "Hel
在 C++03 中,表达式可以是右值,也可以是左值。 在 C++11 中,表达式可以是: 右值 左值 x值 gl值 右值 两个类别变成了五个类别。 这些新的表达类别是什么? 这些新类别与现有的右值和左
我正在尝试将 div 向左移动指定数量的像素,我正在使用从此处获得的 slider : http://carpe.ambiprospect.com/slider/archive/v1.3/ 所以从示例
所以我有一个函数需要将 std::vector 作为参数。我想知道声明参数的最佳方式,这样底层数组就不会被深度复制,因为它可能相当大。 // which should I choose? void m
在 C++03 中,表达式要么是右值,要么是左值。 在 C++11 中,表达式可以是: 右值 左值 xvalue glvalue 右值 两类变成了五类。 这些新的表达类别是什么? 这些新类别与现有的右
我正在尝试实现类似 find 的方法来从容器中提取对值的引用,如果找不到该值或该值的类型不兼容,则返回一个默认值。 template const T& get (key_type k, const T
我有以下代码: #include using namespace std; void test(int& a) { cout << "lvalue." << endl; } void tes
我的搜索发现许多关于右值绑定(bind)到左值的帖子,但没有任何类似的帖子。对不起,如果它是重复的。 struct StrHolder { StrHolder(std::string&& s)
这是一个后续问题 C++0x rvalue references and temporaries 在上一个问题中,我问过这段代码应该如何工作: void f(const std::string &);
为什么这不起作用: ostream& operator' lvalue to 'std::basic_ostream&&'| error: initializing argument 1 of '
偶尔,我被问到一个技巧问题:x++ 和 ++x 哪个不能在 c 中留值?很多人告诉我++x不能,因为++x的汇编代码不返回寄存器。我对此表示怀疑。所以我做了一些实验。 C 代码: #include
所以这个问题与我为实际问题选择的解决方案有关,为了尽可能提供完整的图片,这个问题是这样的:基本上我有一个带有很多模板参数的函数,我正在尝试暴露给 Python。与用宏做一些噩梦般的事情来消除我需要的所
指针很简单。有一些内存保存着一个地址。要获得(有意义的)值,取消引用返回地址指向的内存中包含的值。 引用以某种方式做一些类似的事情:它们持有指向一个临时对象的“链接”。但是当我分配或使用引用时会发生什
下面是一些示例代码: #include class Foo { public: explicit Foo(int x) : data(x) {}; Foo& operator++() {
背景 以下代码块出现在 Scott Meyers 的名著 "Effective C++" 中第 3 项: class TextBlock { public: ... const cha
我是一名优秀的程序员,十分优秀!