使用 std::map<K,V>其中 V 没有可用的默认构造函数
我有一个作为 std::map
实现的符号表.对于值,无法通过默认构造函数合法地构造值类型的实例.但是,如果我不提供默认构造函数,则会出现编译器错误,如果我使构造函数断言,我的程序可以正常编译但在 map<K,V>::operator []
如果我尝试使用它来添加新成员.
I have a symbol table implemented as a std::map
. For the value, there is no way to legitimately construct an instance of the value type via a default constructor. However if I don't provide a default constructor, I get a compiler error and if I make the constructor assert, my program compile just fine but crashes inside of map<K,V>::operator []
if I try to use it to add a new member.
有没有办法让 C++ 在编译时禁止 map[k]
作为左值(同时允许它作为 r 值)?
Is there a way I can get C++ to disallow map[k]
as an l-value at compile time (while allowing it as an r-value)?
顺便说一句:我知道我可以使用 Map.insert(map<K,V>::value_type(k,v))
插入到地图中.
BTW: I know I can insert into the map using Map.insert(map<K,V>::value_type(k,v))
.
一些人提出了相当于改变值类型的解决方案,以便地图可以在不调用默认构造函数的情况下构造一个.这与我想要的结果完全相反,因为它将错误隐藏到以后.如果我愿意,我可以简单地从构造函数中删除断言.我想要是让错误发生得更快;在编译时.但是,似乎没有办法区分 operator[]
的 r-value 和 l-value 使用,所以看起来我想要的东西无法完成,所以我只需要分配一起使用.
several people have proposed solution that amount to altering the type of the value so that the map can construct one without calling the default constructor. This has exactly the opposite result of what I want because it hides the error until later. If I were willing to have that, I could simply remove the assert from the constructor. What I Want is to make the error happen even sooner; at compile time. However, it seems that there is no way to distinguish between r-value and l-value uses of operator[]
so it seems what I want can't be done so I'll just have to dispense with using it all together.
推荐答案
你不能让编译器区分 operator[] 的两种用法,因为它们是同一个东西.Operator[] 返回一个引用,因此分配版本只是分配给该引用.
You can't make the compiler differentiate between the two uses of operator[], because they are the same thing. Operator[] returns a reference, so the assignment version is just assigning to that reference.
就我个人而言,除了快速和肮脏的演示代码之外,我从不使用运算符 [] 来表示地图.使用 insert() 和 find() 代替.请注意,make_pair() 函数使插入更易于使用:
Personally, I never use operator[] for maps for anything but quick and dirty demo code. Use insert() and find() instead. Note that the make_pair() function makes insert easier to use:
m.insert( make_pair( k, v ) );
<小时>
在 C++11 中,你也可以这样做
In C++11, you can also do
m.emplace( k, v );
m.emplace( piecewise_construct, make_tuple(k), make_tuple(the_constructor_arg_of_v) );
即使没有提供复制/移动构造函数.
even if the copy/move constructor is not supplied.
相关文章