5

Here's the code that I have a problem with:

class Foo {
public:
    Foo() :
        memberArray{Bar(1), Bar(3), Bar(2)}
    {}
    struct Bar {
        Bar(int param1) {  }
    };
private:
    std::array<Bar,3> memberArray;
//  Bar memberArray[3];    // Using a raw array like this instead compiles fine..
};

I'm using GCC 4.6.1, and compiling for c++11. How should I initialise my std::array?

Cœur
  • 37,241
  • 25
  • 195
  • 267
evo_race
  • 61
  • 1
  • 4

5 Answers5

6

Since array<T, N> is actually a struct, the fully braced version needs {{ .. }} (the inner ones are for the array member of the array<T, N> object). The spec does not allow brace elision here. It only allows it in a declaration of the form

Type var = { ... };

So you have to use fully braced syntax

Foo() :
    memberArray{{Bar(1), Bar(3), Bar(2)}}
{}

This is not a GCC bug, but required by the spec.

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • But that doesn't compile, at least for g++ 4.5.2. It says: error: no matching function for call to 'std::array::array()' – TonyK Dec 27 '11 at 17:20
  • 1
    @TonyK : We're discussing what is or isn't legal syntax, not compiler implementation deficiencies. – ildjarn Dec 27 '11 at 20:32
  • @ildjarn: So you think my comment is simply irrelevant? That's a strange position to take. – TonyK Dec 27 '11 at 20:38
  • 1
    @TonyK : Yes, to an extent, since the fact that it doesn't compile in that version of GCC merely indicates a bug in that version of GCC, and has no bearing on the validity of the answer. – ildjarn Dec 27 '11 at 20:43
  • @ildjarn: Read my comment. That's why I said "at least". Does it compile for later versions? I don't know, I don't have them. If it doesn't, you look pretty silly. If it does, well, I did the best I could. I think it's clear that my comment was not focused on compiler implementation deficiencies. Why don't you tell us what your compiler says, instead of giving me stick? – TonyK Dec 27 '11 at 21:07
  • @TonyK I think he merely said that you should better post your insight to the GCC bugtracker instead of as a comment to my answer. If you want to collect people that have the latest GCC version and want people to try the correct code on other compilers, perhaps asking in the C++ chat or on the question's comments itself would collect more users. Your comment starts with "But", but I did not claim that G++4.5.2 accepts this code. – Johannes Schaub - litb Dec 27 '11 at 21:15
  • 2
    @TonyK : Don't take everything so personally -- no one's giving you "stick". The _standard_ says this answer is correct; any given compiler's behavior is irrelevant. – ildjarn Dec 27 '11 at 21:16
  • @ildjarn: Everybody knows that the new C++11 standard is open to interpretation on many levels. But please tell me this: Does your C++ compiler accept Johannes' code, or not? And if so, what compiler do you use? – TonyK Dec 27 '11 at 21:20
  • @TonyK it has been interpreted in various ways and issue reports have been written. See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1270 – Johannes Schaub - litb Dec 27 '11 at 21:23
  • This is like pulling teeth! Does it compile, or doesn't it? That's an easy enough question to answer! – TonyK Dec 27 '11 at 21:25
  • @TonyK: if you read the link http://stackoverflow.com/questions/8192185/using-stdarray-with-initialization-lists posted in the comments to the question, it mentions the form working on gcc4.6.1 and later. – ex0du5 Dec 27 '11 at 21:35
  • @ex0du5: I don't think it's unreasonable of me to ask Johannes and ildjarn whether they are able to compile the code that Johannes recommends here. Especially as the code that I posted in my answer compiles (demonstrably) under g++ 4.5.2. Johannes? ildjarn? – TonyK Dec 27 '11 at 21:47
  • @TonyK the code that you provided is invalid C++, as explained by my answer. I'm not trying to make my code work on GCC. It has no relevance whether it compiles on GCC4.6 or GCC4.5 to me. – Johannes Schaub - litb Dec 27 '11 at 21:52
  • 1
    @TonyK : I don't use a C++11 compiler, but I'm capable of reading _normative_ text and understanding it. Are you satisfied now? – ildjarn Dec 27 '11 at 21:52
  • This is kind of surreal. I provide a working code fragment in my answer; Johannes provides a non-working code fragment, but it's better than mine because it's apparently standards-compliant; and ildjarn adjudicates on the basis of not being able to compile any kind of code fragment at all. What's wrong with you people? --THROWS UP HANDS IN HORROR-- – TonyK Dec 27 '11 at 21:57
  • @TonyK : You did not provide a working code fragment -- you provided a code fragment that happens to compile on a _defective_ compiler, but it would not compile on a _conformant_ compiler. What's wrong with you that you can't understand that correct behavior is not governed by existing implementations, but by what the standard mandates? – ildjarn Dec 27 '11 at 22:14
  • @ildjarn: Can you point me to a conformant compiler? If not, you are just blowing smoke out of your arse. You are saying,"Code fragment X is better than code fragment Y, because code fragment X complies with the standard (although there is no compiler in existence that can compile code fragment X)." Is that your position? – TonyK Dec 27 '11 at 22:18
  • @TonyK : Are you aware that the C++11 standard has only been official for a matter of months? There is no 100% conformant compiler yet. I'd warrant that Clang tip-of-trunk gets this right, though, and more than likely GCC 4.7.x. – ildjarn Dec 27 '11 at 22:19
  • 1
    @ildjarn yes, GCC4.7 gets my code right, and gives a warning for TonyK's code, and an error for the OP's code. As for the different behavior regarding TonyK's and the OP's code, I filed a GCC PR: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51689 – Johannes Schaub - litb Dec 27 '11 at 22:24
  • @ildjarn: I'm kind of a practical man, so I actually took the trouble to see whether Johannes' code compiles under g++ 4.7.x. And in fact it does. Not because "I'd warrant it" -- but because it does. HTH. – TonyK Dec 27 '11 at 22:28
  • 1
    @TonyK : If you were _that_ practical, you would read the standard yourself and not rely on existing (likely deficient) implementations to attempt to prove your point. ;-] – ildjarn Dec 27 '11 at 22:28
  • @Johannes: And I can confirm your result. Under g++ 4.7.x, my code generates a warning, and your code doesn't. So now we're all in agreement! – TonyK Dec 27 '11 at 22:31
  • 1
    @TonyK: I kind of _specifically_mentioned_ compilers that the code worked for, so your continued hysteria and caps seems quite baffling. I understood your desire completely - it's important to see if compiler vendors are interpreting the regulations according to the advice being given. But Johannes Schaub's form is specifically mentioned in the link and standards compliant compilers are given that properly perform translation. I don't know why those internetizens are less reliable than the two people you demanded answer, and I wouldn't agree with that assesment if explained. – ex0du5 Dec 28 '11 at 17:13
  • @TonyK: See emsr's comment to the original post in that link for the confirmation I am pointing out. He specifically did the test of multiple forms and reports their compilation. – ex0du5 Dec 28 '11 at 17:17
2

As a workaround, you can have a function return an instance of this array.

#include <array>

class Foo {
public:
    Foo() :
        memberArray(makeMemberArray())
    {}
    struct Bar {
        Bar(int param1) {  }
    };
private:
    std::array<Bar,3> memberArray;
//  Bar memberArray[3];    // Using a raw array like this instead compiles fine..

    static std::array<Bar, 3> makeMemberArray() { 
      std::array<Bar,3> a = {Bar(1), Bar(2), Bar(3)}; 
      return a; 
    }
};

I think uniform initialization is supposed to allow what you are doing, except it might not be implemented by the compiler.

UncleBens
  • 40,819
  • 6
  • 57
  • 90
0

Building on Johannes Schaub - litb's answer... at least GCC will allow you to use an abbreviated syntax (leaving out the, pointless, class name):

Foo() :
    memberArray{{ {1}, {3}, {2} }}
{}

instead of

Foo() :
    memberArray{{Bar(1), Bar(3), Bar(2)}}
{}

I, personally, only use something like the second version when I'm initializing an array of polymorphic pointers:

Foo() :
    memberArray{{
        dynamic_cast<Bar*>(new BarA(1)),
        dynamic_cast<Bar*>(new BarB(3)),
        dynamic_cast<Bar*>(new BarC(2))
    }}
{}
Compholio
  • 733
  • 1
  • 9
  • 17
0
#include <stdio.h>
#include <array>
#include <iostream>

void test1(){ printf("hello 0\n");}
void test2(){printf("hello 1\n");}
void test3(){printf("hello 2\n");}



typedef void (*functionPointerType)(); //from fastled demoreel100 was   typedef void (*SimplePatternList[])();

    void (*functptr[])() = { test1, test2, test3 } ; //classic way
    std::array<functionPointerType, 3> funcList{ {test1, test2, test3} }; //  double-braces required in C++11 prior to




class FuncContainClass {
public:
std::array<functionPointerType, 3> funcList; 


};

FuncContainClass funcClass;

int main()
{

funcClass.funcList[1] = &test2;
funcClass.funcList[1]();



functptr[0]();

std::cout << funcList.size() << std::endl;
funcList[1]();
    return 0;
}

`

I found this post because I was simply trying to have an std::array of functions but I think I found a solution to this problem as well. I found if I created a typeDef of the function pointer it worked.

-5

Try this (it works for g++ 4.5.2):

  Foo() :
      memberArray (std::array<Bar,3> {Bar(1), Bar(3), Bar(2)})
  {}
TonyK
  • 16,761
  • 4
  • 37
  • 72
  • 1
    @ildjarn: That was a bit childish of you, to downvote my answer because I posted working code. – TonyK Dec 28 '11 at 00:43
  • 4
    That's a bit childish of you to assume that I'm the only one willing to downvote an incorrect answer (and you really need to learn the actual definition of "working"). Sorry to disappoint you. – ildjarn Dec 28 '11 at 04:11