How does program know array size?

Pages: 12
Furry Guy, I must admit I when to deduction guide but then noticed coder777 was talking about constants, so I'm thinking an array of constants rather than a constant array and can't think of how to do that with deduction guide.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <array>
#include <iostream>

int main()
{
    // deduction guide for array creation: since C++17?
    std::array const arr1 {3, 1, 4};
    for (const auto &val : arr1)
        std::cout << val << ' ';
    std::cout << '\n';
    
    std::array<const int, 3> arr2 {1, 2, 3};
    for (const auto &val : arr2)
        std::cout << val << ' ';
    std::cout << '\n';

    const int arr3[] {4, 5, 6};
    for (const auto &val : arr3)  // Get a warning 
        std::cout << val << ' ';
    
    return 0;
}
Tested with VS 2019 set to C++20, Code::Blocks set to C++17 ISO:
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <array>

int main()
{
   const std::array<int, 3> arr1 { 1, 2, 3 };

    // arr1[1] = 5;  // unmodifiable

   for (const auto& itr : arr1)
   {
      std::cout << itr << ' ';
   }
   std::cout << '\n';

   const std::array arr2 { 4, 5, 6 };

   // arr2[1] = 12; // unmodifiable

   for (const auto& itr : arr2)
   {
      std::cout << itr << ' ';
   }
   std::cout << '\n';

   std::array<int, 3> const arr3 { 7, 8, 9 };

   // arr3[1] = 5;  // unmodifiable

   for (const auto& itr : arr3)
   {
      std::cout << itr << ' ';
   }
   std::cout << '\n';

   std::array const arr4 { 10, 11, 12 };

   // arr4[1] = 125; // unmodifiable

   for (const auto& itr : arr4)
   {
      std::cout << itr << ' ';
   }
   std::cout << '\n';

   const int arr5[] { 13, 14, 15 };

   // arr5[1] = 125; // unmodifiable

   for (const auto& itr : arr5)
   {
      std::cout << itr << ' ';
   }
   std::cout << '\n';
}

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

No warnings, no errors unless I uncomment any of the element assignments.
Last edited on
I'm just trying to get my head around if std::array const arr1 {3, 1, 4}; is a constant array of int or an array of int constants...and if it makes any difference.

PS the warning I marked would be from the static analyser...I'm not bothered by it.

Edit:
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
41
42
43
44
45
#include <array>
#include <iostream>
#include <string_view>

template <typename T> constexpr auto type_name()
{
    std::string_view name, prefix, suffix;

    name   = __FUNCSIG__;
    prefix = "auto __cdecl type_name<";
    suffix = ">(void)";
    name.remove_prefix(prefix.size());
    name.remove_suffix(suffix.size());
    return name;
}

int main()
{
    std::array const arr1 {3, 1, 4};
    std::cout << "\nstd::array const arr1 {3, 1, 4};\n";
    std::cout << "decltype(arr1)    is " << type_name<decltype(arr1)>() << '\n';
    std::cout << "decltype(arr1[0]) is " << type_name<decltype(arr1[0])>() << '\n';

    std::array<const int, 3> arr2 {1, 2, 3};
    std::cout << "\nstd::array<const int, 3> arr2 {1, 2, 3}; \n";
    std::cout << "decltype(arr2)    is " << type_name<decltype(arr2)>() << '\n';
    std::cout << "decltype(arr2[0]) is " << type_name<decltype(arr2[0])>() << '\n';

    std::array<int, 3> arr5 {1, 2, 3};
    std::cout << "\nstd::array<int, 3> arr5 {1, 2, 3}; \n";
    std::cout << "decltype(arr5)    is " << type_name<decltype(arr5)>() << '\n';
    std::cout << "decltype(arr5[0]) is " << type_name<decltype(arr5[0])>() << '\n';

    const int arr3[] {4, 5, 6};
    std::cout << "\nconst int arr3[] {4, 5, 6}; \n";
    std::cout << "decltype(arr3) is " << type_name<decltype(arr3)>() << '\n';
    std::cout << "decltype(arr3[0]) is " << type_name<decltype(arr3[0])>() << '\n';

    int arr4[] {4, 5, 6};
    std::cout << "\nint arr4[] {4, 5, 6}; \n";
    std::cout << "decltype(arr4) is " << type_name<decltype(arr4)>() << '\n';
    std::cout << "decltype(arr4[0]) is " << type_name<decltype(arr4[0])>() << '\n';

    return 0;
}

std::array const arr1 {3, 1, 4};
decltype(arr1)    is const class std::array<int,3>
decltype(arr1[0]) is const int&

std::array<const int, 3> arr2 {1, 2, 3};
decltype(arr2)    is class std::array<int const ,3>
decltype(arr2[0]) is const int&

std::array<int, 3> arr5 {1, 2, 3};
decltype(arr5)    is class std::array<int,3>
decltype(arr5[0]) is int&

const int arr3[] {4, 5, 6};
decltype(arr3) is const int[3]
decltype(arr3[0]) is const int&

int arr4[] {4, 5, 6};
decltype(arr4) is int[3]
decltype(arr4[0]) is int&
Last edited on
Well, VS 2019 indicates all of those std::arrays are are const std::array<int, 3U> no matter where the const is located. Same situation with the plain arrays marked const.

The range based for loops are similarly situated regardless of where the const. is placed. const int&.

It goes without saying that std::arrays are static sized, what happens if a std::vector is const created?
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
#include <iostream>
#include <vector>

int main()
{
   const std::vector vec1 { 1, 2, 3 };

   // vec1[1] = 125;     // unmodifiable
   // vec1.push_back(4); // unmodifiable
   // vec1.erase(2);     // unmodifiable

   for (const auto& itr : vec1)
   {
      // itr++; // unmodifiable
      std::cout << itr << ' ';
   }
   std::cout << '\n';

   for (auto const& itr : vec1)
   {
      // itr++; // unmodifiable
      std::cout << itr << ' ';
   }
   std::cout << '\n';

   std::vector const vec2 { 4, 5, 6 };

   // vec2[1] = 125;       // unmodifiable
   // vec2.push_back(125); // unmodifiable
   // vec2.erase(2);       // unmodifiable

   for (auto& itr : vec2)
   {
      // itr++; // unmodifiable
      std::cout << itr << ' ';
   }
   std::cout << '\n';
}

Location of const doesn't appear to matter. A const std::vector<> is created that can't be be resized, element values can't be modified.

And the iterator in the range based for loops are const iterators even if const isn't used.

As a result of this experimentation I really do like using std::array over using a plain array more than I used to.

Learned something useful about vectors constness as well.
I really do like using std::array over using a plain array more than I used to.


Yes - as C++20 as constexpr. Note however that you can't use std::string as the type with constexpr. Consider:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <array>
#include <string_view>
#include <string>

using namespace std::string_view_literals;
using namespace std::string_literals;

int main()
{
	constexpr std::array myarr {"foo", "bar"};	// OK type const char*
	constexpr std::array svarr {"foo"sv, "bar"sv};	// OK type std::string_view
	//constexpr std::array strarr {"foo"s, "bar"s};	// NO. Can't use std::string in constexpr
	const std::array strarr {"foo"s, "bar"s};	// OK type std::string but run time not compile time
}


For an array of 'strings', probably svarr is the best using string_view as the underlying type and with compile time allocation.
Topic archived. No new replies allowed.
Pages: 12