1

Say I get an int from a lambda function ran at initialization of a class object. Is it possible to use that int to define the size of a std::array? Something like the following code.

#include <array>
#include <vector>
#include <iostream>

class Test1 {

    public:
        Test1( std::vector<int> vec1 ) :
            nvars([&vec1]() -> int { return vec1.size()+1; }())
        {
        };

        const int nvars;
        // ******This isn't allowed!!!!!!!!!
        const std::array<int,nvars> arr;
};

int main() {
    std::vector<int> vec{1,2,3,4};
    Test1 test1(vec);
    std::cout << "nvars: " << test1.nvars << std::endl;

    return 0;
}

I am a C++ beginner so any other advice will be welcome.

Javier Garcia
  • 539
  • 1
  • 4
  • 15
  • 2
    no. The size is part of the arrays type. The type of the member must be know for the definition of the class – 463035818_is_not_an_ai Nov 14 '22 at 14:01
  • 3
    There's a difference between a run time constant (i.e. a value which cannot change during execution of the program), and a compile time constant (i.e. a value known to the compiler). Integer template parameters are required to be compile time constants. – john Nov 14 '22 at 14:03
  • Is there any functional difference between `[&vec1]() -> int { return vec1.size()+1; }()` and `vec1.size()+1`? Edit : I guess it casts to `int`. – François Andrieux Nov 14 '22 at 14:08
  • I had an idea which didn't work out: https://stackoverflow.com/questions/74433344/what-can-be-used-in-the-simple-template-id-of-a-class-template-deduction-guide – MSalters Nov 14 '22 at 14:37
  • Do have a look at https://stackoverflow.com/questions/38932089/can-i-initialize-an-array-using-the-stdinitializer-list-instead-of-brace-enclo though – MSalters Nov 14 '22 at 14:38

1 Answers1

1

No. The size of the array is part of its type. You cannot let it be determined at runtime.

You can have it be determined at compile time, if you do pass a std::array to the constructor. Since C++17 there is CTAD (class template argument deduction) which lets you write:

#include <array>


template <size_t N>
class Test1 {

    public:
        Test1( std::array<int,N> vec1 ) :
            arr(vec1)
        {
        };

        const std::array<int,N> arr;
};

int main() {
    std::array vec{1,2,3,4};
    Test1 test1(vec);
}

Live Demo

test1 is of type Test1<4>. Note that Test1<4> is a distinct different type than eg Test<5> or Test<24>. If you want one type to have a member array of different size, make it a std::vector.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185