Re: Using the STL for scientific programming
Am 06.10.2011 20:38, schrieb Christopher Dearlove:
On Oct 5, 10:38 pm, Daniel Kr?gler<daniel.krueg...@googlemail.com>
wrote:
Am 05.10.2011 21:51, schrieb piotrN:
#include<vector>
class MyObject;
struct MyData {
std::vector<MyObject> myObjectVector;
};
class MyObject {};
int main() { MyData myData; return 0; }
Of course if you instantiate an object - its type must be complete to
do the destruction for instance.
This code is *not* portable and still invokes undefined behaviour by the
C++ Standard. There is no guarantee that will be well-formed, even though it
often is for existing implementations. Just as a sketch, there is nothing
that prevents a library implementation to define std::vector as follows
Just to be clear, I'm not disagreeing with you. But that form of
argument isn't really satisfactory, what's the standard (1989 or 1993,
please) citation that makes it so? What follows is my best guess, but
with questions, the biggest one of which is, have I got it right?
The obvious stating point is (1989 standard) 17.4.3.6 2 fifth point
which makes the vector undefined if instantiated when MyObject is
incomplete. But then where is the vector instantiated? I think
14.6.4.1 says preceding the definition that refers to the
instantiation, i.e. within struct MyData. Which fails.
I think that a compiler is supposed to instantiate std::vector<MyObject>
in this example based on (I'm quoting the new C++11 standard) the
combination of 9.2 [class.mem] p10:
"Non-static (9.4) data members shall not have incomplete types."
and of 14.7.1 [temp.inst] p1:
"Unless a class template specialization has been explicitly instantiated
(14.7.2) or explicitly specialized (14.7.3), the class template
specialization is implicitly instantiated when the specialization is
referenced in a context that requires a completely-defined object type
or when the completeness of the class type affects the semantics of the
program."
As a practical litmus test, make above data member a static data member
and the code should be well-formed for recent compilers.
Note that the situation was not really clear for the C++03 standard, and
9.2 p10 was added as part of the resolution
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#328
to fix this.
It should also highlighted that this first instantiation process (within
the definition of MyData) is only allowed to instantiate the
declarations (but not the definitions) of all member functions, member
classes, scoped member enumerations, static data members and member
templates.
The further instantiation of the required constructor and destructor
shall not happen before the first use, which is within the main function.
This means, that it is technically possible to define std::vector such
that the code would be well-formed and well-defined for this example. I
was only presenting an example that demonstrates the current leeway of
implementations (including the potential advantages of them, think of
compile-time switches based on some type properties of T which again
would require the completeness of T).
But (still 14.6.4.1) if struct MyData were templated (on MyObject)
then the point of instantiation would move to where MyData is
instantiated, i.e. in main, where MyObject is complete?
Sure. The same happens for std::vector in the example as well.
Is there any
problem with that myData relies on an implicit destructor?
Not in this example, because the destructor of vector<MyObject> won't be
instantiated before main - irrespective whether MyData is a template or not.
And (looking ahead - I'm waiting for BSI to publish the 2011 standard)
I believe shared_ptr can be used in the original case, unlike vector.
Yes, it can, see the last sentences of my posting to which you replied.
Is there an explicit exception for shared_ptr, or how else does it get
round it? What else gets round it?
The standard has added extra wording for shared_ptr, unique_ptr
(non-array-specializations), declval, and a little number of others to
make this well-defined. The magical phrase is
"The template parameter T of X may be an incomplete type."
HTH & Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]