4

I'm trying to instantiate an array of a class where the constructor takes two arguments, and initialize it in the same line.

Conceptually, I want to do something like this:

foo::foo (int A, int B = 10)
{
    V1 = A;
    V2 = B;
}

foo Myfoo[3] = { (1, 100), (2, 300), (5, 100) };
// what I _don't_ want to do is create individual objects like this:
// foo Myfoo1(1, 100); 
// foo Myfoo2(2, 300);
// foo Myfoo3(5, 100);

What I found is that when the constructor is called the arguments are not as expected. The B argument always shows up as the default value of 10. Just in tinkering I threw in additional arguments in the array initialization.

foo Myfoo[3] = { (0, 1, 100), (2, 300, 0), (0, 5, 100, 0) }; 

To my surprise it compiled without error, but I didn't pursue this too far, because it didn't make sense to me - but I was able to affect the problem

Does anyone have an idea on how I should code this? I've already worked around the problem but I'm curious how it should be done properly.

3 Answers 3

3

With the usage of (1, 100), you're just passing one int with value 100 to the constructor of foo. The comma-operator just discards the 1st operand, and returns the 2nd operand here. (It doesn't work in the way as you expected like foo Myfoo1(1, 100); or foo(1, 100);.)

You should use {} ( list initialization (since C++11) ) instead of (), i.e.

foo Myfoo[3] = { {1, 100}, {2, 300}, {5, 100} };
Sign up to request clarification or add additional context in comments.

2 Comments

I tried this using MS Visual Studio 2010 and it will not compile, giving the error message: 1>d:\dev\arraytest\arraytest\arraytest.cpp(24): error C2552: 'Myfoo' : non-aggregates cannot be initialized with initializer list 1> 'foo' : Types with user defined constructors are not aggregate
@ElRonaldo Does your compiler support C++11? Or it might have some trouble with list initialization. I trid a live demo here.
2

The cause of the problem has already been explaind by @songhuanyao.

I can think of the following ways to resolve the problem.

Option 1

Use {} instead of () to construct objects.

foo Myfoo[3] = { {1, 100}, {2, 300}, {5, 100}};

Option 2

Use foo explitly with () to construct objects.

foo Myfoo[3] = { foo(1, 100), foo(2, 300), foo(5, 100) };

Option 3

Use foo explitly with {} to construct objects.

foo Myfoo[3] = { foo{1, 100}, foo{2, 300}, foo{5, 100}};

2 Comments

your option 2 worked for me! but doesn't that create an additional foo each time? I'm wondering if this is one of those cases where you really need to have a copy constructor defined (but I'm not sure I used the right terminology)
@ElRonaldo, In theory, there is a copy no matter which option you choose. I am not sure whether a compiler is able to elide any of those copy operations.
1

We need to use {} instead of () and code is working as expected

#include<iostream>

using namespace std;

class Test
{
    public:
            Test(int a, int b = 10)
            {
                    x = a;
                    y = b;
                    cout << "C-tor" << endl;
            }
            void show()
            {
                    cout << " x = " << x << " y = " << y << endl;
            }
    private:
            int x;
            int y;
};


int main()
{

    Test obj[3] = {{10,20},{30,40}, {50,60}};
    obj[0].show();
    obj[1].show();
    obj[2].show();
    return 0;
 }

Above code produces expected output:

C-tor

C-tor

C-tor

x = 10 y = 20

x = 30 y = 40

x = 50 y = 60

I hope it helps!

3 Comments

Thanks for your answer Sinha! I copied your example into Visual Studio 2010 and it would not compile - getting the same error message as songyuanyao's. What compiler did you use?
Thanks @ElRonaldo I'm using g++ on Ubuntu 18.04LTS
gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04) On this version I compile the code.

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.