
Le 20/04/13 17:03, Olaf Peter a écrit :
Hello,
g++ (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2)
and maybe the last changes ... breaks my code now which is basically:
namespace {
struct id_string { static boost::once_flag flag; typedef std::map<int, std::string> map_type; ...
static void do_init(token_id_string& self) { insert(self.m_map)(x, "y")(...) ; }
std::string const& operator()(id::type id) const { boost::call_once(flag, &id_string::do_init, *this);
map_iterator s = m_map.find(id); ... } };
Hi, the error /usr/local/include/boost/thread/detail/invoke.hpp:406:65: error: invalid initialization of non-const reference of type '{anonymous}::id_string&' from an rvalue of type '{anonymous}::id_string' says you that the parameter (const) can not be used where a non-const is expected. Shouldn't the operator be declared non-const std::string const& operator()(id::type id) ; In addition if you want to pass a reference you would need to use boost::ref(). The following compile well without the patch struct id_string { static boost::once_flag flag; static void do_init(id_string & ) {} void operator()() { boost::call_once(flag, &id_string::do_init, boost::ref(*this)); } }; Note that the following compiles struct id_string { static boost::once_flag flag; static void do_init(id_string & ) {} void operator()() { std::bind(&id_string::do_init, std::ref(*this))(); } void operator()(int) const { std::bind(&id_string::do_init, *this)(); } }; I would expect that the preceding fails as *this is a 'id_string const&' and do_init expects an 'id_string &'. This would explain why with the patch it worked as the patch was calling to std::bind. But if make use of the class { id_string id; //id(); id(1); } I get the following error gcc.compile.c++ /tmp/bin.v2/boost/bin.v2/libs/thread/test/call_once_p.test/gcc-4.6.1.0x/debug/threading-multi/sync/mutual_exclusion/once/call_once/call_once_pass.o In file included from /usr/include/c++/4.6/functional:56:0, from ../../../boost/thread/detail/invoke.hpp:34, from ../../../boost/thread/pthread/once_atomic.hpp:17, from ../../../boost/thread/once.hpp:20, from sync/mutual_exclusion/once/call_once/call_once_pass.cpp:26: /usr/include/c++/4.6/tuple: In constructor ‘constexpr std::_Head_base<_Idx, _Head, false>::_Head_base(const _Head&) [with unsigned int _Idx = 0u, _Head = id_string]’: /usr/include/c++/4.6/tuple:162:44: instantiated from ‘constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(const _Head&, const _Tail& ...) [with unsigned int _Idx = 0u, _Head = id_string, _Tail = {}]’ /usr/include/c++/4.6/tuple:423:24: instantiated from ‘constexpr std::tuple<_T1>::tuple(const _T1&) [with _T1 = id_string]’ /usr/include/c++/4.6/functional:1186:70: instantiated from ‘std::_Bind<_Functor(_Bound_args ...)>::_Bind(_Functor&&, _Args&& ...) [with _Args = {const id_string&}, _Functor = void (*)(id_string&), _Bound_args = {id_string}]’ /usr/include/c++/4.6/functional:1450:41: instantiated from ‘typename std::_Bind_helper<_Functor, _ArgTypes>::type std::bind(_Functor&&, _ArgTypes&& ...) [with _Functor = void (*)(id_string&), _ArgTypes = {const id_string&}, typename std::_Bind_helper<_Functor, _ArgTypes>::type = std::_Bind<void (*(id_string))(id_string&)>]’ sync/mutual_exclusion/once/call_once/call_once_pass.cpp:206:43: instantiated from here /usr/include/c++/4.6/tuple:97:25: erreur: use of deleted function ‘id_string::id_string(const id_string&)’ sync/mutual_exclusion/once/call_once/call_once_pass.cpp:194:8: erreur: ‘id_string::id_string(const id_string&)’ is implicitly deleted because the default definition would be ill-formed: sync/mutual_exclusion/once/call_once/call_once_pass.cpp:194:8: erreur: use of deleted function ‘boost::once_flag::once_flag(const boost::once_flag&)’ ../../../boost/thread/pthread/once_atomic.hpp:59:5: erreur: declared here Could you tell me if works for you after rolling back the patch and adding the suggested changes on your code? Best, Vicente