4

Consider the following class:

class A {
    const int arr[2];
public:
      A() { }
};

Is it possible to initialize arr from the constructor initializer list or in any other way than on the line where it is declared (i.e. const int arr[2] = {1,2};)?

Note that I'm interested in methods that work with C++98!

12
  • 2
    It's started! Explicit non-C++11-ness in questions. (Nothing wrong with that) Commented Nov 17, 2011 at 17:59
  • This is a famous deficiency of C++98, which is why we now have C++11! Commented Nov 17, 2011 at 17:59
  • 5
    Whats this silliness? Please make this tag be c++03 ... or do we want a cc++ tag or maybe a c#java tag? Commented Nov 17, 2011 at 18:06
  • 2
    @JohannesSchaub-litb: I didn't realize there was no slash :-( Please feel free to modify/fix/delete as you see fit. C++-obsolete might be the most universal name. Commented Nov 17, 2011 at 18:10
  • 2
    I've changed the C++-9803 tag to c++98, as that's the specific version that was requested. I support having c++98, c++03 etc tags, but lumping every old version together into one tag is brokenness waiting to happen. What happens when C++2x comes out, and c++-obsolete now includes c++11? Commented Nov 17, 2011 at 18:29

3 Answers 3

4

By wrapping them in a struct, e.g.:

class A
{
    struct Data
    {
        int arr[2];
    };

    Data const arr;
public:
    A() : arr( someOtherStruct ) {}
};

This does mean that to access the data, you'd have to write arr.arr. It's possible to avoid that by inheriting from the struct:

struct PrivateDataForA
{
    int arr[2];
};

class A : private PrivateDataForA
{
public:
    A() : PrivateDataForA( someOtherStruct ) {}
};

This does make the name of the struct visible outside of the class (which might be an advantage—client code could pass you one as an argument).

If you don't have an instance of the struct handy, say because you want to fill it with values calculated from arguments to the constructor, you can use a static member function:

class A : private PrivateDataForA
{
    static PrivateDataForA createInitializer( int a, int b );
public:
    A( int a, int b ) : PrivateDataForA( createInitializer( a, b ) )
    {
    }
};

For the OP’s concrete example:

#include <iostream>
#include <stddef.h>

typedef ptrdiff_t   Size;
typedef Size        Index;

template< class Element, Size n >
struct Array{ Element elem[n]; };

class A {
    Array<int, 2> const arr_;       // const int arr[2];

    A& operator=( A const& );       // No such.

    static Array<int, 2> const& oneAndTwo()
    {
        static Array<int, 2> const a = {1, 2};
        return a;
    }

public:
    A(): arr_( oneAndTwo() ) {}
    int at( Index i ) const { return arr_.elem[i]; }
};


int main()
{
    using namespace std;

    A o;
    for( int i = 0;  i < 2;  ++i )
    {
        cout << o.at( i ) << endl;
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Essentially you're advocating use of boost::array<>/std::tr1::array<> -- why not say that directly?
@ildjarn Because I wasn't. I'm not actually that familiar with either of those classes, and wrapping data in a struct is a useful technique to know in general (although only really necessary when C-style arrays are being used).
Well given that std::array<> is now standard, it's a good thing to be familiar with. ;-] (And again, it's exactly what your answer is describing.)
2

Initializing array elements to non-zero values requires C++11 support.

In C++03, it's only possible to value-initialize your array, resulting in each element's value being 0:

class A {
    const int arr[2];
public:
    A() : arr() { }
};

For the relevant C++03 standardese, see this question and answer:
How can i use member initialization list to initialize it?

(I'm going to assume that by C++98 you mean not C++11, i.e. that C++03 is acceptable. If this assumption is wrong, please say so.)

11 Comments

-1: OP specifically gave non-zero values as an example, and non-C++11 as a requirement.
@Tomalak : I mentioned the only thing that is possible to do, which obviously also indicates what isn't possible to do (everything that wasn't mentioned). Don't be petty. And to be clear, the concrete question is "Is it possible to initialize arr from the constructor initializer list or in any other way than on the line where it is declared?" OP's example aside, I directly answer that question.
Don't call me petty. If the OP used non-zero element values as his example, it's pretty clear that that's what he wants. You're just conveniently ignoring half the question.
No, you're absolutely being petty. A direct question was asked, a direct answer was given. Just because the OP's example isn't satisfiable doesn't mean the question wasn't answered accurately.
Nonsense, and I shan't argue about it any more. There is really no need for you to get personal just because somebody downvoted your answer.
|
-2

No. It's not.

7 Comments

You're not getting an upvote for that. Sometimes being right is not enough :-)
@KerrekSB: I think you'll find that this is as correct and accurate and useful as any C++98 answer is going to get!
C++98 did already allow the array() syntax explained in the other answer. it just wasn't called value initialization. so as the question is posed, the answer should be "yes it is possible"
@JohannesSchaub-litb But not usefully:-). (Why would you want an array whose values can only be 0?) Other solutions are possible, however; the flat statement that it's not possible is wrong, at least from a practical point of view. (Technically, you use a struct, rather than an array, but if all the struct contains is the array, it comes out to the same thing.)
@james i agree and if i wouldnt.be.in a train on a.phone i would.already have posted that :-X
|

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.