#6711 closed Feature Requests (wontfix)
with unordered_map using interprocess basic_string in shared memory, find and [] are annoying
| Reported by: | Owned by: | ||
|---|---|---|---|
| Milestone: | To Be Determined | Component: | None |
| Version: | Boost 1.49.0 | Severity: | Problem |
| Keywords: | interprocess, unordered_map, container | Cc: | jdy@…, igaztanaga@… |
Description
When using an interprocess basic string such as:
typedef boost::interprocess::allocator<
char,
boost::interprocess::managed_mapped_file::segment_manager
> char_allocator_t;
typedef boost::interprocess::basic_string<
char,
std::char_traits<char>,
char_allocator_t
> key_type;
map, flat_map (and unordered_map) all require that one have an externally created temporary of that type (key_type) created that can temporarily hold the results of a std::string or char*. This requires code of the form:
// A temporary string that allocates from the mapped file
struct shm_clean { // cleanup shared memory on stack-unwind
shm_clean() {
boost::interprocess::shared_memory_object::remove("StupidSharedMemory");
}
~shm_clean() {
boost::interprocess::shared_memory_object::remove("StupidSharedMemory");
}
} cleaner;
boost::interprocess::managed_shared_memory
stupid(boost::interprocess::create_only ,"StupidSharedMemory" ,500);
key_type key_val(stupid.get_segment_manager());
mymap_in_shared_memory[key_val = mystring.c_str()] = junk;
This is barely ok when we are working with mutable memory regions, but when I am working in a read-only memory map, it is annoying.
Please see this thread:
http://thread.gmane.org/gmane.comp.lib.boost.devel/228874
Bug posted at request of Ion Gaztañaga
See sister ticked for boost::containers
https://svn.boost.org/trac/boost/ticket/6710
Joel
Change History (11)
comment:1 by , 11 years ago
| Resolution: | → wontfix |
|---|---|
| Status: | new → closed |
comment:2 by , 11 years ago
The standard doesn't require you to not have extra find() overloads, does it?
comment:3 by , 11 years ago
It does, because it can break valid code. Consider this:
#include <cassert>
#include <functional>
struct source {};
struct value {
value(source&&) {}
};
void foo(value const& x) { std::equal_to<value>(x); }
#if defined(ADD_TEMPLATE)
template <typename T>
void foo(T const& x) { std::equal_to<value>(x); }
#endif
int main() {
foo(source());
}
Note that ADD_TEMPLATE adds a template overload, as you're suggesting. Defining ADD_TEMPLATE causes it to fail:
$ g++-mp-4.7 --std=c++0x demo.cpp $ g++-mp-4.7 --std=c++0x demo.cpp -DADD_TEMPLATE demo.cpp: In instantiation of 'void foo(const T&) [with T = source]': demo.cpp:19:17: required from here demo.cpp:15:24: error: invalid initialization of reference of type 'const value&' from expression of type 'const source' demo.cpp:9:6: error: in passing argument 1 of 'void f(const value&)'
The same could happen if a template overload was added for find.
comment:4 by , 11 years ago
VC11 says "error C2082: redefinition of formal parameter 'x'" for the first "std::equal_to<value>(x);"
Without equal_to(), it compiles fine.
Even if it didn't, why not just replace the original find() with a template variant?
comment:5 by , 11 years ago
Sorry, I messed up that example, here's a better one. This one doesn't use rvalue references because I don't have access to an appropriate compiler at the moment, but it demonstrates why a template method would break valid code (foo calls std::equal_to in the same way that find does):
#include <functional>
struct source {};
struct value {
value(source&) {}
bool operator==(value const&) const { return true; }
};
struct pseudo_container
{
std::equal_to<value> eq;
#if defined(USE_A_TEMPLATE)
template <typename T>
void foo(T const& x) {
eq(x, x);
}
#else
void foo(value const& x) {
eq(x, x);
}
#endif
};
int main() {
pseudo_container x;
source s;
x.foo(s);
}
comment:6 by , 11 years ago
Isn't that because the value constructor takes a non-const & to source? With const& it works.
comment:7 by , 11 years ago
But value types are allowed to use non-const constructors from arbitrary types, I can't stop them doing that.
comment:8 by , 11 years ago
Sorry, 'are allowed to construct with non-const references from arbitrary types'.
comment:9 by , 11 years ago
Hmm, equal_to is the real problem, as it requires the two types to be the same. You'd need an equal_to variant that doesn't.
comment:10 by , 11 years ago
Yes, but equal_to is actually a template parameter, whose concept is defined by the standard so I can't change it.

Closing as "won't fix", since boot unordered is an implementation of the standard unordered containers, and this would be a break from the standard. It would also be worse when using
std::equal_toorboost::hashsince it would have to cast for every call to those function objects rather than just once for the call tooperator[].