#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_to
orboost::hash
since it would have to cast for every call to those function objects rather than just once for the call tooperator[]
.