-
Why does std::vector require its elements to be assignable?
Perhaps it's just too early in the morning for me to think straight, but... I can't think of a reason why std::vector would need its elements to be assignable.
The only operation I can think of that would require the elements to be assignable is the vector's own assignment operator, but why would an operation like push_back() require invoking the assignment operator of its elements? Even in the case of a reallocation, can't the vector use placement new to copy-construct the new elements from the old ones?
-
Re: Why does std::vector require its elements to be assignable?
Because you can assign elements.
Code:
void setAllToZero(vector<int> & vec){
foreach(vec, iterator){
*iterator = 0;
}
}
-
Re: Why does std::vector require its elements to be assignable?
Also
Code:
vector<int> vec(10);
vec[3] = 1;
-
Re: Why does std::vector require its elements to be assignable?
It would be nice if the requirement could be reduced to move-assignable for move-aware types.
-
Re: Why does std::vector require its elements to be assignable?
But suppose you don't do any of those things? Suppose all you do is add elements to the vector using push_back()? Aren't member functions of template classes only instantiated if they're actually used? So shouldn't a piece of code that only calls push_back() compile even if the element type is not assignable?
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
HighCommander4
But suppose you don't do any of those things? Suppose all you do is add elements to the vector using push_back()? Aren't member functions of template classes only instantiated if they're actually used? So shouldn't a piece of code that only calls push_back() compile even if the element type is not assignable?
No - it is a template which means the the requirements are the same for all types used to instantiate the vector. If an object is created on the stack and then passed to push_back, then the object has to be deep copied. I don't see what the big deal is. Vector isn't special. All sequence containers require the types to be assignable unless you are inserting pointers.
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
HighCommander4
The only operation I can think of that would require the elements to be assignable is the vector's own assignment operator, but why would an operation like push_back() require invoking the assignment operator of its elements? Even in the case of a reallocation, can't the vector use placement new to copy-construct the new elements from the old ones?
Placement new? How is that relevant to the question? The object still has to be copied one way or the other and this is done through either the assignment operator or copy constructor. :confused:
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
kempofighter
Placement new? How is that relevant to the question? The object still has to be copied one way or the other and this is done through either the assignment operator or copy constructor. :confused:
But by using placement new, you can do the push_back with the cctor instead of the assignment operator.
Although, granted, I don't think there are many cases where a type would be copy constructable but not assignable.
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
kempofighter
Placement new? How is that relevant to the question? The object still has to be copied one way or the other and this is done through either the assignment operator or copy constructor. :confused:
The element type in my case is copy constructible, just not assignable.
Quote:
Originally Posted by Lindley
Although, granted, I don't think there are many cases where a type would be copy constructable but not assignable.
Any type with a const or reference member variable falls into this category. In my case, it's map<T, U>::value_type, which is pair<const T, U>. I can, of course, simply store pair<T, U> in the vector, but then when I insert it into the map, an extra copy has to be made to convert it to pair<const T, U>, and it bothers me to have to make this extra copy.
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
Lindley
But by using placement new, you can do the push_back with the cctor instead of the assignment operator.
Although, granted, I don't think there are many cases where a type would be copy constructable but not assignable.
That's a true statement. The standard agrees with you as well. However sorting and inserting could certainly result in either copy construction or assignment for every object that needs to be shifted around. That is why I think that the question is irrelevant. The containers have many capabilities and for that reason the standard says this:
Quote:
The type of objects stored in these components must meet the requirements of CopyConstructible
types (20.1.3), and the additional requirements of Assignable types.
I guess I don't understand what prompted the question. Is it possible that certain uses of the containers may not cause compiler errors because the code doesn't do anything that results in assignment? I guess so. I have never tried that. I guess it depends on the compiler. Perhaps the OP should post an example that produces errors and then explain to us why he thinks that the code ought to compile. That might be an interesting discussion.
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
HighCommander4
But suppose you don't do any of those things? Suppose all you do is add elements to the vector using push_back()? Aren't member functions of template classes only instantiated if they're actually used? So shouldn't a piece of code that only calls push_back() compile even if the element type is not assignable?
Interesting question. The answer seems to be no based on the results of testing this example. I received on error on std::fill but I don't even use that algorithm in the program. That is pretty weird and I didn't expect that at all. What examples have you tried to compile and what were your results?
Code:
#include <iostream>
#include <vector>
struct NonAssignableType
{
// default constructors are fine.
int i;
private:
NonAssignableType& operator=(const NonAssignableType& rhs);
};
int main()
{
std::vector<NonAssignableType> naTypeObjects;
naTypeObjects.push_back(NonAssignableType());
return 0;
}
For the rest of the gurus, is that normal for compilers to generate code for all or some of the algorithm templates just because I created an STL container with a user defined type? Perhaps this is my compilers way of enforcing the requirement of the C++ standard that the type be assignable.
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
HighCommander4
Any type with a const or reference member variable falls into this category. In my case, it's map<T, U>::value_type, which is pair<const T, U>. I can, of course, simply store pair<T, U> in the vector, but then when I insert it into the map, an extra copy has to be made to convert it to pair<const T, U>, and it bothers me to have to make this extra copy.
I disagree with that completely. user defined types are always assignable by default. The question is does the default assignment operator work correctly? The only way that the type isn't assignable is if you declare the assignment operator to be non-public. If you have a class with a const member then that member isn't assignable but what about the others? If there are no others then there is nothing to assign and the default assignment operator is benign. So there is no problem there. For trivial user defined types this is never an issue due to the default assignment operator and copy constructor. The only time that your question makes sense is when the copy constructor is needed. If it is needed then you need to implement the assignment operator or disable it by declaring it non-public. The copy/swap idiom makes the design of the assignment operator easy so I am not sure why you would ever want to make an object copyable but not assignable in the first place.
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
kempofighter
I disagree with that completely. user defined types are always assignable by default. The question is does the default assignment operator work correctly? The only way that the type isn't assignable is if you declare the assignment operator to be non-public. If you have a class with a const member then that member isn't assignable but what about the others? If there are no others then there is nothing to assign and the default assignment operator is benign. So there is no problem there. For trivial user defined types this is never an issue due to the default assignment operator and copy constructor. The only time that your question makes sense is when the copy constructor is needed. If it is needed then you need to implement the assignment operator or disable it by declaring it non-public. The copy/swap idiom makes the design of the assignment operator easy so I am not sure why you would ever want to make an object copyable but not assignable in the first place.
I'm not sure I follow. pair<const T, U> is not assignable:
Code:
#include <utility>
using namespace std;
int main()
{
pair<const int, int> a;
pair<const int, int> b;
a = b;
}
Code:
/usr/include/c++/4.2/bits/stl_pair.h: In member function std::pair<const int, int>& std::pair<const int, int>::operator=(const std::pair<const int, int>&):
/usr/include/c++/4.2/bits/stl_pair.h:69: error: non-static const member const int std::pair<const int, int>::first, can't use default assignment operator
test.cpp: In function int main():
test.cpp:8: note: synthesized method std::pair<const int, int>& std::pair<const int, int>::operator=(const std::pair<const int, int>&) first required here
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
HighCommander4
But suppose you don't do any of those things? Suppose all you do is add elements to the vector using push_back()? Aren't member functions of template classes only instantiated if they're actually used? So shouldn't a piece of code that only calls push_back() compile even if the element type is not assignable?
In that case I would rethink your container needs. Sounds like you need std::stack instead. The right container for the right job.
You could always write your own vector, for only a few functions, it really wouldn't be that complicated, you could borrow gcc's implementation and strip it to what you need.
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
ninja9578
In that case I would rethink your container needs. Sounds like you need std::stack instead. The right container for the right job.
You could always write your own vector, for only a few functions, it really wouldn't be that complicated, you could borrow gcc's implementation and strip it to what you need.
I need to iterate over the elements after adding them, so stack and queue are out of the question.
Interestingly, deque seems to work (and meets all my needs). Since the major difference between vector and deque is that deque never has to reallocate its elements, while vector does, this suggests that vector needs to invoke the assignment operator on its elements while reallocating.
I'm still curious as to why this is - why can't the elements be copied using placement new + copy constructor during reallocation?
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
HighCommander4
I'm still curious as to why this is - why can't the elements be copied using placement new + copy constructor during reallocation?
Because:
Code:
vector<string> vec;
vec.push_back("hello world");
string & ref = vec[0];
vec[0] = "hello mars";
If you literally replaced vec[0] with a new string, where does ref point?
Also, some classes have very slow ctors, and very fast assignment operators.
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
HighCommander4
I need to iterate over the elements after adding them, so stack and queue are out of the question.
Interestingly, deque seems to work (and meets all my needs). Since the major difference between vector and deque is that deque never has to reallocate its elements, while vector does, this suggests that vector needs to invoke the assignment operator on its elements while reallocating.
I'm still curious as to why this is - why can't the elements be copied using placement new + copy constructor during reallocation?
If the template implementation happens to use "=" anywhere in the code, you get the compiler error. If the implementation happens to not use "=" anywhere, you don't get the compiler error.
What I'm saying is that the C++ compiler is not an "STL compiler". The compiler proper doesn't know the requirements of an STL container. All it knows is the C++ syntax in front of it. There are compilers that compiles STL code that goes against the STL requirements without any errors. Not because the compiler knows the STL requirements and is being tricky, it's just that by chance, the internal code didn't trigger a copy, copy ctor, whatever. You take that same code and try to compile it on another compiler, you may just get those errors.
I've even seen compilers in "debug" mode compile code that goes against the STL requirements, and fail compilation on the release mode. To be exact, the VC 2005 has this, where if you don't define a predicate function as const, the debug version compiled fine, while the release didn't. The reason is as I stated -- a compiler only knows the syntax that it's given. When "debug" is compiled, a different set of code is compiled that doesn't trigger the "const" being in play, while release did.
So your std::deque "solution" probably only works by chance if the STL requirements are that the type must be copyable and assignable.
Regards,
Paul McKenzie
-
Re: Why does std::vector require its elements to be assignable?
You can always build your own container. You only have a few functions that you are using, so create your own container and you can have it do whatever you want. STL is there for convenience, it doesn't mean you can't write your own classes. Lots and lots of people write their own containers for various reasons.
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
HighCommander4
I'm still curious as to why this is - why can't the elements be copied using placement new + copy constructor during reallocation?
They might be. However as Paul pointed out if the compiler generates all of the member functions for std::vector, std::deque, or whatever container that you are using and something in those implementations uses operator= then your code will not compile unless operator= is defined for the type T.
In the earlier example that i showed you the problem had nothing to do with the push_back. When I instantiate a template with a user defined type the compiler is generating all of the member functions and even some algorithms that do require assignment. I do not get any errors related to push_back. I think that your other question about when compiler generates the templates is a better question. In my case I do not understand why the compiler tried to generate code for std::fill when I hadn't even used that algorithm for the type in question. If std::fill hadn't caused the problem then one of the container member functions might have.
-
Re: Why does std::vector require its elements to be assignable?
I am not sure in what context you claimed pair is not assignable. But look at this example.
Code:
pair<int, string> p1(1, "Mike");
pair<int, string> p2 = p1;
After the assignment, p2 becomes (1, "Mike").
Quote:
Originally Posted by
HighCommander4
I'm not sure I follow. pair<const T, U> is
not assignable:
Code:
#include <utility>
using namespace std;
int main()
{
pair<const int, int> a;
pair<const int, int> b;
a = b;
}
Code:
/usr/include/c++/4.2/bits/stl_pair.h: In member function std::pair<const int, int>& std::pair<const int, int>::operator=(const std::pair<const int, int>&):
/usr/include/c++/4.2/bits/stl_pair.h:69: error: non-static const member const int std::pair<const int, int>::first, can't use default assignment operator
test.cpp: In function int main():
test.cpp:8: note: synthesized method std::pair<const int, int>& std::pair<const int, int>::operator=(const std::pair<const int, int>&) first required here
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
Paul McKenzie
If the template implementation happens to use "=" anywhere in the code, you get the compiler error. If the implementation happens to not use "=" anywhere, you don't get the compiler error.
What I'm saying is that the C++ compiler is not an "STL compiler". The compiler proper doesn't know the requirements of an STL container. All it knows is the C++ syntax in front of it. There are compilers that compiles STL code that goes against the STL requirements without any errors. Not because the compiler knows the STL requirements and is being tricky, it's just that by chance, the internal code didn't trigger a copy, copy ctor, whatever. You take that same code and try to compile it on another compiler, you may just get those errors.
I've even seen compilers in "debug" mode compile code that goes against the STL requirements, and fail compilation on the release mode. To be exact, the VC 2005 has this, where if you don't define a predicate function as const, the debug version compiled fine, while the release didn't. The reason is as I stated -- a compiler only knows the syntax that it's given. When "debug" is compiled, a different set of code is compiled that doesn't trigger the "const" being in play, while release did.
So your std::deque "solution" probably only works by chance if the STL requirements are that the type must be copyable and assignable.
Regards,
Paul McKenzie
Let's look at default constructibility.
vector requires its element type to be default constructible precisely when you use an operation that requires default construction, e.g. the constructor that creates n default-constructed elements, or resize(n) which adds default constructed elements if there are fewer than n elements in the vector. If the element type is not default constructible and you don't use these operations, your code compiles just fine.
Why should the assignability requirement be any different? (And please don't say "because the standard says so". I'd like to know the rationale behind the standard.)
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
LarryChen
I am not sure in what context you claimed pair is not assignable. But look at this example.
Code:
pair<int, string> p1(1, "Mike");
pair<int, string> p2 = p1;
After the assignment, p2 becomes (1, "Mike").
If you read my post carefully you'll see that I said pair<const T, U> is not assignable - that is, whenever one of the elements of the pair is const. Of course there is no problem if neither of the elements are const.
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
ninja9578
In that case I would rethink your container needs. Sounds like you need std::stack instead. The right container for the right job.
You could always write your own vector, for only a few functions, it really wouldn't be that complicated, you could borrow gcc's implementation and strip it to what you need.
All sequence containers have the same requirement that the type used to instantiate the template be copyable and assignable. This is a common requirement for them all. Therefore using a stack (which uses a deque by default) might not help depending on your implementation. In my case I get lucky because deque's push_back implementation is totally different then vector's. I poked around a little more and I found out that my vector::push_back function is implemented in terms of the insert member function which is rather complex. As I digged deeper I found out that it has to do with dependencies on some of the other internal member functions of the vector. Although a push_back could be very simple in some cases the fact that those dependencies on other functions exist mean that they have to be completely compiled. Along the way one of those functions that has to be compiled happens to invoke operator=.
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
kempofighter
All sequence containers have the same requirement that the type used to instantiate the template be copyable and assignable. This is a common requirement for them all. Therefore using a stack (which uses a deque by default) might not help depending on your implementation. In my case I get lucky because deque's push_back implementation is totally different then vector's. I poked around a little more and I found out that my vector::push_back function is implemented in terms of the insert member function which is rather complex. As I digged deeper I found out that it has to do with dependencies on some of the other internal member functions of the vector. Although a push_back could be very simple in some cases the fact that those dependencies on other functions exist mean that they have to be completely compiled. Along the way one of those functions that has to be compiled happens to invoke operator=.
Right - now we're getting to the heart of the matter.
What I really want to know is, is it possible to implement vector in a way that certain operations can be performed without the requirement of assignability?
I suspect the answer is yes, and if so, the next question that naturally arises is, why doesn't the standard mandate such an implementation?
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
HighCommander4
Let's look at default constructibility.
vector requires its element type to be default constructible precisely when you use an operation that requires default construction, e.g. the constructor that creates n default-constructed elements, or resize(n) which adds default constructed elements if there are fewer than n elements in the vector. If the element type is not default constructible and you don't use these operations, your code compiles just fine.
Where is the guarantee that the code will compile on all standard conforming compilers? It may have compiled on your compiler, but there is no guarantee it will compile on another one successfully.
The VC 2005 example I illustrated is part and parcel of why you can't assume that you can "beat the system" by providing classes that go against what STL says it must provide. If your implementation just so happens to give you the luxury of compiling without errors, give the implementors a handshake and a pat on the back for a good job. That in no way guarantees that you will have the same luck with another compiler, given that the other compiler is still standard conforming.
Regards,
Paul McKenzie
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
HighCommander4
Let's look at default constructibility.
vector requires its element type to be default constructible precisely when you use an operation that requires default construction, e.g. the constructor that creates n default-constructed elements, or resize(n) which adds default constructed elements if there are fewer than n elements in the vector. If the element type is not default constructible and you don't use these operations, your code compiles just fine.
Why should the assignability requirement be any different? (And please don't say "because the standard says so". I'd like to know the rationale behind the standard.)
They aren't in that context. As Paul said it depends on HOW the STL designer designed that particular version of the code. In my research I found that the vector's push_back depends on other member functions of the vector. Along the way you have many if..else statements that in some cases results in other member functions being called. Even if in your case you don't do anything complex all of the code that push_back depends on must be compiled completely even if at run-time you don't actually execute all of the paths. Go look inside your vector and deque header files and study the implementation details. Since the C++ std requires that all types used for sequence containers be copyable and assignable the compiler isn't violating the standard. They could have implemented the container in some other way, theoretically but they didn't. oh well.
I am taking a closer look at your std::pair example. That seems to be the root cause of your specific troubles. It would have been a good idea to show us a code example in the beginning so that we can understand the specific problem that you are having.
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
Paul McKenzie
Where is the guarantee that the code will compile on all standard conforming compilers? It may have compiled on your compiler, but there is no guarantee it will compile on another one successfully.
The VC 2005 example I illustrated is part and parcel of why you can't assume that you can "beat the system" by providing classes that go against what STL says it must provide. If your implementation just so happens to give you the luxury of compiling without errors, give the implementors a handshake and a pat on the back for a good job. That in no way guarantees that you will have the same luck with another compiler, given that the other compiler is still standard conforming.
Yes, I understand what the standard says and what the implications of using non-standard-conforming behaviour are. I'm just trying to understand the rationale behind the standard.
We have seen that it is possible to implement vector in a way that operations that don't need to call the default constructor will compile without a default constructor. I suspect the same is true for assignment operator. Since implementing vector in this way makes it more flexible, I wonder why the standard doesn't mandate such an implementation. Is it just an omission (or perhaps they didn't think it's important enough) - or is there a good reason?
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
HighCommander4
Right - now we're getting to the heart of the matter.
What I really want to know is, is it possible to implement vector in a way that certain operations can be performed without the requirement of assignability?
I suspect the answer is yes, and if so, the next question that naturally arises is, why doesn't the standard mandate such an implementation?
What difference does it make? It isn't going to happen so even if it were possible how would it help you today? It is obviously possible since as I said earlier the deque::push_back in my STL implementation does exactly what you are talking about. I have no idea if all STL implementations for deque are the same. What does the new standard say? Go read it. there is no point in asking if the standard could be changed since it is essentially finished or asking of the compiler writers could have done something different.
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
kempofighter
What difference does it make? It isn't going to happen so even if it were possible how would it help you today?
It makes a difference because there may be good reason why the standard doesn't require vector to be implemented in this way - perhaps because it's impossible, for some reason that eludes me at the moment - and if so I'd like to know.
Quote:
It is obviously possible since as I said earlier the deque::push_back in my STL implementation does exactly what you are talking about.
But deque is different from vector. vector's push_back() may need to reallocate existing elements, deque's does not.
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
HighCommander4
I'm not sure I follow. pair<const T, U> is
not assignable:
Code:
#include <utility>
using namespace std;
int main()
{
pair<const int, int> a;
pair<const int, int> b;
a = b;
}
Code:
/usr/include/c++/4.2/bits/stl_pair.h: In member function std::pair<const int, int>& std::pair<const int, int>::operator=(const std::pair<const int, int>&):
/usr/include/c++/4.2/bits/stl_pair.h:69: error: non-static const member const int std::pair<const int, int>::first, can't use default assignment operator
test.cpp: In function int main():
test.cpp:8: note: synthesized method std::pair<const int, int>& std::pair<const int, int>::operator=(const std::pair<const int, int>&) first required here
You are right - I didn't think that one through well enough. :blush: It is impossible for default assignment to work for classes with const attributes. I duplicated your problem with a user defined struct type so I understand now. That is a really interesting issue. For any class with non-static, const members you couldn't always use that type with STL sequence containers. The concept of assignment doesn't make sense for that case since after the assignment the two classes could never be equal. So I guess in your case, why does the pair have to be const for T1? I have never run across this problem in any of my designs. In my experience I have always had situations where a class with constants either has a) static constants for all objects b) non-static constants but the class is a singleton type or c) used enum type for declaring sets of constants. With an enum decl within a class the class you don't have to instantiate the enum to use the constants and the values are the same for all class instances so it is similar to having static constants.
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
kempofighter
You are right - I didn't think that one through well enough. :blush: It is impossible for default assignment to work for classes with const attributes. I duplicated your problem with a user defined struct type so I understand now. That is a really interesting issue. For any class with non-static, const members you couldn't always use that type with STL sequence containers. The concept of assignment doesn't make sense for that case since after the assignment the two classes could never be equal. So I guess in your case, why does the pair have to be const for T1? I have never run across this problem in any of my designs. In my experience I have always had situations where a class with constants either has a) static constants for all objects b) non-static constants but the class is a singleton type or c) used enum type for declaring sets of constants. With an enum decl within a class the class you don't have to instantiate the enum to use the constants and the values are the same for all class instances so it is similar to having static constants.
In my case, the vector's element type is map<T, U>::value_type which happens to be pair<const T, U>. There are good reasons why map<T, U> uses pair<const T, U> instead of pair<T, U> as its value type (the keys determine the ordering of the elements, so if you were allowed to change the key, the ordering could change without the map knowing it), but in this case it's really annoying because I can't store its value type in a vector.
My workaround in this case is to store pair<T, U> in the vector, but now I have to do an extra copy when I call map's insert() method because map's insert() method takes a pair<const T, U>& parameter, and so a temporary pair<const T, U> object has to be constructed from the pair<T, U> that's in the vector.
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
HighCommander4
Why should the assignability requirement be any different? (And please don't say "because the standard says so". I'd like to know the rationale behind the standard.)
Maybe the rational was not to constrain the STL implementor?
Adding the extra contraints to the standard may have been thought to be too restrictive and force the implementation down a narrow (and maybe sub-optimal) path.
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
HighCommander4
In my case, the vector's element type is map<T, U>::value_type which happens to be pair<const T, U>. There are good reasons why map<T, U> uses pair<const T, U> instead of pair<T, U> as its value type (the keys determine the ordering of the elements, so if you were allowed to change the key, the ordering could change without the map knowing it), but in this case it's really annoying because I can't store its value type in a vector.
Agreed so maybe you need to rethink the design? I don't understand why you would want to copy the key/value pair into the vector in the first place.
Quote:
Originally Posted by
HighCommander4
My workaround in this case is to store pair<T, U> in the vector, but now I have to do an extra copy when I call map's insert() method because map's insert() method takes a pair<const T, U>& parameter, and so a temporary pair<const T, U> object has to be constructed from the pair<T, U> that's in the vector.
Perhaps you could show us an example and let us know what you are doing? Why are you copying key value pairs from a map into a vector and then back into a map? :confused:
It seems to me that when you do this you have to make copies regardless. Didn't we already agree that the push_back requires copy construction? Likewise when you insert into the map won't it copy construct during the insertion? I'm not sure where you think you are forced into making additional copies that you wouldn't otherwise have to make.
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by HighCommander4
What I really want to know is, is it possible to implement vector in a way that certain operations can be performed without the requirement of assignability?
I suspect the answer is yes, and if so, the next question that naturally arises is, why doesn't the standard mandate such an implementation?
For what it's worth, the C++0x standard specifies fine-grained requirements for each of the STL container member functions rather than imposing requirements on the container as a whole. In particular, push_back() (for both vector and deque) requires only that the element type be copy constructible, not assignable (if anyone's interested, the relevant sections are 23.2.3/16 and 23.2.1/13).
I reported this issue to GCC's libstdc++, and they promptly fixed their vector implementation :thumb:
-
Re: Why does std::vector require its elements to be assignable?
That was an interesting read. The thread is old, but I think I'll chip in my two cents: ;)
Why not use a boost::ptr_vector? Basically, it is a self-maintained container of pointers to objects, making all the requirements met by default.
That and boost::ptr_vector is always a great container for large objects. :thumb:
-
Re: Why does std::vector require its elements to be assignable?
Quote:
Originally Posted by
monarch_dodra
That was an interesting read. The thread is old, but I think I'll chip in my two cents: ;)
Why not use a boost::ptr_vector? Basically, it is a self-maintained container of pointers to objects, making all the requirements met by default.
The same reason C++ arrays aren't like Java arrays: we want to avoid extra allocations when not necessary.