2

I have two classes A and B in C++11. There's a static array in class A, which is used in class B. Here is the simplified problem:

// A.h
class A {
public:
    static int const a[4];
};

// A.cpp
int const A::a[4] = {1,2,3,4};

// B.h
class B {
public:
    void method();  
};

// B.cpp
void B::method() {
    for(auto const& it:a) {
        /* do something */
    }
}

It works, but it requires the explicit definition of the array size. I would like to change the content of the array initializer from time to time, at compile time, without the manual redefinition of its size.

What would be an equivalent, but more efficient way to do this?

14
  • 5
    How about std::vector? Commented Aug 1, 2017 at 14:19
  • 1
    @Someprogrammerdude there is a great difference between the two. Commented Aug 1, 2017 at 14:20
  • 1
    What do you mean? Change size of the array at compilation time or at runtime? Commented Aug 1, 2017 at 14:20
  • 1
    @underscore_d, since std::array::size is marked as constexpr, I don't see any issues with that. Commented Aug 1, 2017 at 14:30
  • 1
    @VolodymyrLashko - You don't follow, the OP doesn't want to be forced into modifying the size parameter of the type in the class definition whenever they update the initializer for the array. With std::array they are forced to do so. Only with a C-style array can the size be omitted. Commented Aug 1, 2017 at 14:34

1 Answer 1

10

If it's const you can't do it. If it's constexpr however, you can:

class A {
public:
    static constexpr int a[] = {1, 2, 3, 4};
};

Just move the initializer into the class definition. Then you can omit the array size completely.


A caveat to note, as pointed out by @SergeBallesta, is that you cannot skip on defining the storage for the array if you odr-use it. Which your example obviously does in the range for loop (it needs pointers to the beginning and past the end). So your cpp file still needs a const int A::a[]; declaration.

In C++17 you can at least make the definition header only thanks to inline variables being added to the language.

Sign up to request clarification or add additional context in comments.

3 Comments

It works only if the type of 'a' is a literal like 'int'. What if its type is 'std::string'?
@blzs - It works for any type which has a constexpr constructor. std::string doesn't, but it doesn't mean you can't define types that are.
Much better now :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.