Couple std::vector Questions

Hello there!

So I have two main questions regarding std::vector

1: Is there a non-copyable version of it? I'm not asking about a std::vector containing non-copyable objects, I want a std::vector that's not copyable, so you have to pass it by reference or pointer.

2: Is there any way to customize the size type of std::vector? For me it seems the default is always size_t, but I would like to change this so I can avoid casting. It would be ideal to be able to set it to uint32_t, int32_t, uint16_t, or any other integer type. So when I call myVector.size() and whatnot, it returns the size type I specify.

Any information is very much appreciated!
The solution for #2 is, unless you have some reason not to, to use size_t any time you have a variable that will receive the value of std::vector::size(), or that will be compared to that value, or that will be used as the parameter for std::vector::operator[]().
Im rusty on this stuff but if you wrapped vector in a class that prevented copying, I think you lose x=y; copies too, which is 'bad' for most useful containers? There may be a way around this, but I don't know it off the top of my head. A wrapper class would solve #2 as well, but #2 isnt a real issue and doing so seems odd. I am old school, and don't really like the idea of limiting things to only work one way -- this bungles everything for reuse of the code most of the time. Instead, pass it like it should be passed correctly every time. Jacking limitations into your tools that solve no real problems other than babysitting the programmer ... is 100% always a bad idea.
Last edited on
Using a size_t all the time sounds incredibly wasteful and potentially dangerous if you're not careful when you have to use types that are smaller than size_t. Which this is precisely why I want to use something else whenever I want to.

So basically what I'm gathering is I should implement my own vector type and pass the size type as a template parameter.
1: Is there a non-copyable version of it? I'm not asking about a std::vector containing non-copyable objects, I want a std::vector that's not copyable, so you have to pass it by reference or pointer.

What problem do you want to solve?

Being unable to copy an object doesn't mean you can't pass it by value.
1
2
3
4
5
int main() 
{
  void by_value(std::unique_ptr<int> x);
  by_value(nullptr); 
}

Notice that the parameter is constructed in-place, std::unique_ptr<int> has a converting constructor from nullptr_t.

If I had to guess, you want to prevent expensive copies of the vector's contents. In which case you would make the vector's contents moveable and non-copyable.

Is there any way to customize the size type of std::vector? For me it seems the default is always size_t, but I would like to change this so I can avoid casting. It would be ideal to be able to set it to uint32_t, int32_t, uint16_t, or any other integer type. So when I call myVector.size() and whatnot, it returns the size type I specify.


Yes. The type of a vector's size is given by typename std::vector<T>::size_type, which comes directly from its allocator's member type size_type. You can change it by writing your own allocator.

Edit: improve example
Last edited on
Using a size_t all the time sounds incredibly wasteful
Hence why I said "unless you have a reason not to". For example, making a large array of sizes that are known ahead of time to always be smaller than 200 would be a valid reason not to use size_t. Another valid reason would be sending the size in binary format across a platform-agnostic channel (such as as network socket), since the size of size_t is platform-dependent.

potentially dangerous if you're not careful when you have to use types that are smaller than size_t
That's why you should avoid using small types to hold numeric values (using small types to hold other things, such as characters, bytes, etc. is fine). If you have a vector of size, say, one million, and you need to communicate this size using a short, you probably only have two choices: either pass the largest value short can hold, or throw an exception. Personally, I don't like either option.
Bottom line, size_t exists for a reason: to hold sizes of memory objects. It's your choice to use something else, but it's also your responsibility to deal with the consequences.
"So basically what I'm gathering is I should implement my own vector type and pass the size type as a template parameter."

to a degree. You don't have to re-invent vector, you can use it as your starting point.
Have you thought about ignoring the issue and just making sure you use vector<int>& in parameters? You could make a macro or typedef for it if you really want to focus on keeping sanity I guess.

I fiddled with some code and came up with this, only problem is that I don't think this has the original operators that string has, so you cannot do name = "something";, I imagine you need to type another assignment operator to the string class and make it set the strings assignment... You should not use this in production code, I usually don't bother with operator overloading, or inheriting stl structures.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// Example program
#include <iostream>
#include <string>
#include <vector>

template<class T>
class check_copy : public T{
    public:
    check_copy(){}
    check_copy( const check_copy& c){std::cout<<"Something Copied!\n";}
};

void checking_copy(check_copy<std::string> copy)
{
    (void)copy;
}

void checking_no_copy(check_copy<std::string>& copy)
{
    (void)copy;
}

int main()
{
  check_copy<std::string> name;
  
  check_copy<std::string> book = name;
  
  std::cout << "What is your name? ";
  
  getline(std::cin,name);
  
  std::cout << "Hello, " << name << "\n";
  
  checking_copy(book);
  
  std::cout << "!\n";
  
  checking_no_copy(book);
}
Last edited on
Topic archived. No new replies allowed.