Problems with Vectors in Microsoft C++

Pages: 12

I'm having a problem using STL vectors in Visual Studio 2017. I know there are some differences in Microsoft C++ and other versions but I can't believe that this is the cause. My problem is that after I declare a vector, I can't use some of C++17 functions like size. Visual Studio says it does not know what size is. Also, I don't seem to be able to initialize a vector using the two parameter constructor that provides size and initial value. See code below. I would really appreciate any suggestions. I have the latest version of Visual Studio. Is this just a Microsoft problem or am I missing something?

1
2
3
4
5
6
7
8
9
10
11
12

#include <vector>
using namespace std;

int main()
{
 vector<int> v1(10);
 int x = v1.size();

 vector<int> v2(10,2);

Last edited on
There is no problem of this kind with Visual Studio 2017.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <vector>

int main()
{
    const std::vector<int> v1(12) ; // size: 12, front: 0
    const std::vector<int> v2( 12, 3 ) ; // size: 12, front: 3
    const std::vector<int> v3{12} ; // size: 1, front: 12
    const std::vector<int> v4{ 1, 2, 3, 4, 5 } ; // size: 5, front: 1
    const std::vector<int> v5{ v4.rbegin(), v4.rend() } ; // size: 5, front: 5
    
    std::cout << v1.size() << ' ' << v1.front() << '\n' 
              << v2.size() << ' ' << v2.front() << '\n'
              << v3.size() << ' ' << v3.front() << '\n'
              << v4.size() << ' ' << v4.front() << '\n'
              << v5.size() << ' ' << v5.front() << '\n' ;
}

https://rextester.com/IQZIGK37686
closed account (E0p9LyTq)
The size() method (std::vector's size() member function) isn't new to C++17, no language standard needs to be set.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <vector>

int main()
{
   std::vector<int> v1(10);

   int i = v1.size();

   std::cout << "size is " << v1.size() << '\n';

   std::vector<int> v2(20, 2);

   std::cout << "size is " << v2.size() << '\n';
}
size is 10
size is 20

You could have problems with your particular installation of Visual Studio, mine works fine.
Last edited on
The size() method isn't new to C++17

C++17 introduced std::size.
https://en.cppreference.com/w/cpp/iterator/size
Last edited on
closed account (E0p9LyTq)
C++17 introduced std::size.

The OP was using vector's size() member function, not std::size(). Look at his sample code.

If he wants to use C++17 language features he needs to enable that language standard. It isn't set to C++17 by default.

Just tested the following sample with Visual Studio Community 2017 version 15.9.5, using the default language standard that doesn't specify C++17, and it compiles and runs cleanly:

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <vector>
#include <iterator>
 
int main() 
{
    std::vector<int> v = { 3, 1, 4 };
    std::cout << std::size(v) << '\n'; 
 
    int a[] = { -5, 10, 15 };
    std::cout << std::size(a) << '\n';
}

So, if he is unable to use either std::size() or std::vector.size() there is likely a problem with his setup.
Last edited on
What's the difference between std::sixe(v) and v.size()
What's the difference between std::sixe(v) std::size(v) and v.size()

Nothing, except when v is an array, in which case v.size() will not compile.
Is it better than sizeof(arr)/sizeof(arr[0]) for c-strings?

edit:
I found this at cppreference for std::size,
1
2
3
4
5
template <class T, std::size_t N>
constexpr std::size_t size(const T (&array)[N]) noexcept
{
    return N;
}


I didn't get constexpr std::size_t size(const T (&array)[N]) noexcept apart from it's a function with identifier 'size' returning size_t and which is a constexpr.

Also how do functions know the size of one dimensional c-style arrays when they're passed? I know that c-style arrays don't store their size anywhere.. and needn't be terminated with a '\0'..

By the way does constexpr force something to be evaluated compile time?
Last edited on
Is it better than sizeof(arr)/sizeof(arr[0]) for c-strings?

Yes, because if arr is a pointer it will fail to compile instead of giving you the wrong result.

Edit: For C-strings you better use strlen because array length != string length.

how do functions know the size of one dimensional c-style arrays when they're passed? I know that c-style arrays don't store their size anywhere..

The size is part of the type.

does constexpr force something to be evaluated compile time?

When a function is marked with constexpr it means that you are allowed to call it at compile-time (in constant expressions), but you can still use it for run-time stuff like a normal functon.
Last edited on
What do you mean size is part of the type? I thought that the size being stored and not being stored was the difference between regular arrays and std::arrays..
The purpose of std::array is mainly to provide a better, less error-prone interface, that is more consistent with other containers in the standard library. An object of type std::array<T, N> does not store the size N as part of the object. Instead N is part of the type so whenever you call size() it will just return N.

1
2
3
4
5
6
7
int x[10]; // x has the type array of 10 ints
           //                         ^
           //               See, the size is part of the type!
                       
std::array<int, 10> y; // y has the type std::array<int, 10>
                       //                                ^
                       //                      See, the size is part of the type! 
Last edited on
How does the snippet I posted handle pointers?
And can you explain the snippet like I had asked? I didn't understand it.
How does the snippet I posted handle pointers?

It doesn't. It's impossible to get the size of an array if all you have is a pointer to the first argument.

And can you explain the snippet like I had asked? I didn't understand it.

I guess you mean the following code.

1
2
3
4
5
template <class T, std::size_t N>
constexpr std::size_t size(const T (&array)[N]) noexcept
{
    return N;
}

Just ignore constexpr and noexcept. They are not relevant to our discussion.

Let's start with something simpler...

The following is a function that accepts an int array of size 10 by reference and returns the size (which is of course 10).

1
2
3
4
std::size_t size(const int (&array)[10])
{
    return 10;
}

The syntax might look a bit weird but that's how you have to write it when you deal with pointers and references to arrays.

Now, if we want this to work for any type T we can turn it into a template.

1
2
3
4
5
template <class T>
std::size_t size(const T (&array)[10])
{
    return 10;
}

We can now use this function template to get the size of any array of size 10.

1
2
3
4
int arr[10];
float arr2[10];
std::cout << size(arr) << '\n'; // calls size<int>(arr) which returns 10
std::cout << size(arr2) << '\n'; // calls size<float>(arr2) which returns 10 

But we cannot yet use it for arrays that has a size other than 10.

1
2
3
int arr3[5];
std::cout << size(arr3) << '\n'; // error, because size<int> expects an int array of
                                 // size 10 but got an int array of size 5. 

To fix this we add another template parameter N that represents the size of the array.

1
2
3
4
5
template <class T, std::size_t N>
std::size_t size(const T (&array)[N])
{
    return N;
}

Now we can use it for array types of any size.

1
2
int arr3[5];
std::cout << size(arr3) << '\n';  // OK, calls size<int, 5>(arr3) which returns 5 
Last edited on
Btw, in case it isn't clear, an array will normally decay into a pointer when passed by value to a function, removing size information.
The trick here is that foo(int (&array)[10]) is how the array is passed by reference, which allows it to retain information about its size (as Peter said).
It doesn't. It's impossible to get the size of an array if all you have is a pointer to the first argument.


Yea sorry I misread your earlier post..

Thanks a lot for the explanation. I did not know templates could be used like that.. I thought it was only for types!

So I would use std::size() for the sake of readability and precaution.

edit:
And thanks Ganado, I think pointer decay is where I got confused!
Last edited on
But I'm still a bit confused. Here is my exact code:

#include <iostream>
#include <vector>
using namespace std;

int main()
{
vector<int> v1; //declares empty vector
vector<float> v2(10); //declares vector with 10 places

vector<int> v3(10, 2); //declares vector with 10 places init to 2

vector<int> v4{ 1,2,3,4 };

int size = v1.size();

v1.

}

C++ tells me that v1.size() is unknown and that vector<int> v3(10,2) is undefined as well.

I don't know what else to do in Visual Studio to make it understand this syntax and functions.

Any help will be greatly appreciated.

The code should work fine if you just remove the v1. line at the end of main.

If that doesn't work make sure you are actually compiling the code as C++, and not some other language.

Posting the exact error message might also be helpful.
What did you set under Properties->C++->Language->C++ Language Standard ?
If that is your exact code, it won't compile because you have a stray "v1.".
Neither of your posts have code that can compile.

This compiles for me:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int> v1;	//declares empty vector
    vector<float> v2(10);	//declares vector with 10 places
    
    vector<int> v3(10, 2);	//declares vector with 10 places init to 2
    
    vector<int> v4{ 1,2,3,4 };
    
    int size = v1.size();
}
(With a warning of unused size variable).
closed account (E0p9LyTq)
@riversr54,

Your code produces two errors. Neither have a thing to do with vector's size() member function.

1
2
Error (active)	E0133	expected a member name	Project1	C:\Programming\My Projects\Project1\Project1\Source.cpp	18	
Error	C2059	syntax error: '}'	Project1	c:\programming\my projects\project1\project1\source.cpp	18	

As others have said you have a stray v1. that is the cause of the errors.

Using Visual Studio 2017 Community, version 15.9.5. The latest as of 9 January 2019.
Pages: 12