#3977 closed Patches (wontfix)
Compile error on make_nvp with reference data member
Reported by: | Owned by: | Robert Ramey | |
---|---|---|---|
Milestone: | Boost 1.43.0 | Component: | serialization |
Version: | Boost 1.42.0 | Severity: | Problem |
Keywords: | Cc: |
Description
When I save the reference data member to the xml_archive by using make_nvp, the compile error occurs.
Attached file 'ref_direct.cpp' is an example program to reproduce problem.
// Compile error! ar << boost::serialization::make_nvp("ref_", &p->ref_);
The error message is below.
error: invalid initialization of non-const reference of type ‘MyInt*&’ from a temporary of type ‘MyInt*'
We can avoid this error using additional variable or using static_cast.
// OK MyInt* pRef = &p->ref_; ar << boost::serialization::make_nvp("ref_", pRef);
// OK ar << boost::serialization::make_nvp("ref_", static_cast<const MyInt * const &>(&p->ref_));
But I think it's not elegant.
My idea is that introducing the new overload of make_nvp function template.
template<class T> inline #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING const #endif nvp<const T> make_nvp(const char * name, const T & t){ return nvp<const T>(name, t); }
It resolves this problem.
Please check 'nvp_const_ref.patch' (attached file).
After apply the patch, I already did the regression test of serialization. All test is passed.
My testing environments are g++ (Ubuntu 4.4.1-4ubuntu9) 4.4.1 and VC++ 9.0 on Windows7.
Attachments (4)
Change History (10)
by , 13 years ago
Attachment: | ref_direct.cpp added |
---|
comment:1 by , 13 years ago
Component: | None → serialization |
---|---|
Owner: | set to |
by , 13 years ago
Attachment: | ref_direct2.cpp added |
---|
replace TAB to white space version of ref_direct.cpp
comment:2 by , 13 years ago
Sorry, In ref_direct.cpp, white spaces and TABs are mixed. I replace all TABs to white spaces in ref_direct2.cpp The program meaning is not changed.
comment:3 by , 13 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
this is not an error.
It's telling you not to pass a non-const.
try fixing it with a const_cast instead.
Your fix will actually create an error in some instances. The test suite doesn't test this specifically.
comment:4 by , 13 years ago
Resolution: | invalid |
---|---|
Status: | closed → reopened |
Thank you for a quick answer.
It's telling you not to pass a non-const. try fixing it with a const_cast instead.
You're right.
I used the static_cast, and it works correctly.
ar << boost::serialization::make_nvp("ref_", static_cast<MyInt * const &>(&p->ref_));
Your fix will actually create an error in some instances. The test suite doesn't test this specifically.
Oh, I overlooked the side effect.
My overload matches to temporary object that shouldn't match.
boost::serialization::make_nvp("MyInt", MyInt());
I still think that I can remove the cast from the client code without a side effect.
I improved my patch to match only object that should match.(nvp_const_ref_ptr_special.patch)
It matches only address of object, it no longer doesn't match temporary objects.
How do you think about it?
Of course I carried out all tests again.
And all of them succeeded.
comment:5 by , 13 years ago
Resolution: | → wontfix |
---|---|
Status: | reopened → closed |
This looks much better.
But I have still have concerns about it.
The reason that we trap a attempt to serialize a non-const is described in the rationale section of the documentation. Your fix overrides that an makes it easier for a user to create an archive which will prove to be unloadable. The current situation requires that the user either change his ref to a const ref or use a const_cast - also he could suppress tracking for that type. So the current situation requires that the user react to a potentially sever problem and take some explicit action to get around it. This saves me uncountable hours of explaining to the user where his problem might be when he later tries to load a tracked item which has changed in the course of serialization. I realize that it's a pain in many cases. But I really can't spend this much time with users who have inadvertently created unloadable archives.
Robert Ramey
comment:6 by , 13 years ago
Now, I have understood your policy. Serializing the reference data member is asymmetric. And we should write such code. But my patch helps hide the such code.
Now, I think to prepare below cast in my code.
template <typename T> T* const& reference_serialize_cast(T* const& t) { return t; }
ar << boost::serialization::make_nvp("ref_", reference_serialize_cast(&p->ref_));
By the way,
The reason that we trap a attempt to serialize a non-const is described in the rationale section of the documentation
means http://www.boost.org/doc/libs/1_42_0/libs/serialization/doc/rationale.html ?
or you mean http://www.boost.org/doc/libs/1_42_0/libs/serialization/doc/serialization.html#references ?
an example program to reproduce problem