lmi
[Top][All Lists]
Advanced

[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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]