[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi] passing objects instead of references to value_cast
From: |
Vadim Zeitlin |
Subject: |
[lmi] passing objects instead of references to value_cast |
Date: |
Mon, 26 May 2008 02:34:32 +0200 |
Hello,
One of the problems we have when compiling LMI with MSVC is that we get
errors such as this:
any_member.hpp(171) : error C2259: 'datum_base' : cannot instantiate abstract
class
any_member.hpp(198) : error C2259: 'datum_base' : cannot instantiate abstract
class
datum_base is indeed an abstract class and the lines 171 and 198 currently
contain respectively
object_->*held_ = value_cast(s, object_->*held_);
and
return value_cast<std::string>(object_->*held_);
i.e. both pass the object to value_cast.
I initially thought that this was a compiler bug but now I'm not so sure:
as value_cast() takes an object and not a reference, the compiler _should_
use the copy ctor to create a temporary copy of an object when passing the
argument. This can be avoided if a temporary is being passed but this is
not the case here. So now I don't understand why does g++ compile this code
rather than why MSVC does not compile it. In the first case it could be
just optimizing the ctor away (although I still don't think it can accept
such code at all) but in the second case the argument is really used.
Besides with a simple example g++ does give an error, e.g. compiling this:
struct B { virtual void Do() = 0; };
struct D : B { virtual void Do() { } };
void foo(B b) { }
int main()
{
D d;
foo(d);
return 0;
}
results in
pass_by_value.cpp:4: error: cannot declare parameter 'b' to be of abstract type
'B'
pass_by_value.cpp:1: note: because the following virtual functions are pure
within 'B':
pass_by_value.cpp:1: note: virtual void B::Do()
pass_by_value.cpp: In function 'int main()':
pass_by_value.cpp:9: error: cannot allocate an object of abstract type 'B'
pass_by_value.cpp:1: note: since type 'B' has pure virtual functions
as expected. So it seems like it's g++ which is confused by templates here
and not MSVC as it shouldn't be possible to pass datum_base to value_cast
like this.
Anyhow, assuming I'm not missing something painfully obvious, this should
be fixed in LMI code. For the first occurrence, i.e. the dummy argument of
value_cast(From from, To dummy) overload, the solution is obvious: we can
just replace "To" with "To *" and pass a pointer to the object instead of
the object itself. This shouldn't result in any ill effects AFAICS except
for being slightly uglier but then this should be used in a very few places
as the usual form of call is value_cast<To>(From) (which can't be used here
because of the well-known C++ quirk of not having a type name for the
result of applying operator ->*).
However I'm not sure about what to do with the other one. Would replacing
"From" with "const From&" unconditionally be acceptable? This is by far the
easiest solution but it does impose some overhead for primitive types which
could be passed by value otherwise. Do you think this is significant in the
context of LMI use? If it is, I can write a patch which dispatches all
primitive types to value_cast by value while using a constant reference for
passing anything else -- will this be acceptable?
Thanks,
VZ
- [lmi] passing objects instead of references to value_cast,
Vadim Zeitlin <=