Re: Moving elements out of an initializer-list
On 9/16/2010 10:59 AM, Johannes Schaub (litb) wrote:
Victor Bazarov wrote:
On 9/16/2010 8:52 AM, Johannes Schaub (litb) wrote:
It seems that the draft C++0x allows a container to act in the following
way:
template<typename T>
struct container {
/* t's backing array is a T[]. Wrap into move iterators to
* make use of move-construction. */
container(initializer_list<T> t)
:v(make_move_iterator((T*)t.begin()),
make_move_iterator((T*)t.end()))
{
}
std::vector<T> v;
};
Notice that i casted the return tpe of t.begin() and t.end() from "T
const*" to "T*", but that seems to be valid. Any comment?
Could you elaborate on why do you need to cast? Thanks!
The above class can be used to do the following
container<T> c{ ifstream("file1.txt"), ifstream("file2.txt") };
And then you have "c.v" a vector of size 2 with those ifstream elements. A
move_iterator returns "T&&" from its "operator*" such that when it iterates
over a "ifstream"-sequence it returns "ifstream&&" which can be moved from.
If I wouldn't have casted, it would return "ifstream const&&", which cannot
be moved from (it's const!).
OK, hold on. The wording of [dcl.init.list/4] is:
"An object of type std::initializer_list<E> is constructed from an
initializer list as if the implementation
allocated an array of N elements of type E, where N is the number of
elements in the initializer list.
Each element of that array is copy-initialized with the corresponding
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
element of the initializer list, .. "
Now, how do you suppose the elements are copy-initialized if the streams
cannot be copied? Have you tried your code anywhere or is it just your
speculation?
But the following does *not* work
vector<ifstream> v{ ifstream("file1.txt"), ifstream("file2.txt") };
Because the const is not casted away, this forces vector to try and copy the
elements, but streams are non-copyable. I think this either shows
- A problem with the wording of initializer_list creation (the backing-up
array is non-const but is inteded to be const?)
- Missing wording that you are not allowed to modify the backing array of an
initializer_list (effectively forbidding moving things out of it)
- Something we can apply to Standard containers to make them more widely
usable with initializer lists.
- A poorly designed initializer_list interface: Why are you allowed to move
things out, but you would need an explicit cast? Either disallow it or
explicitly allow it and make begin/end return "T*".
This is my personal opinion, of course. Please let me hear what you think
about it.
V
--
I do not respond to top-posted replies, please don't ask