Initialize object containing C-style array as member variable (C++)











up vote
13
down vote

favorite
3












Consider the following code:



struct Color  // This struct can't be modified
{
double grey;
double rgb[3];
};

int main()
{
double myRGB[3] = {2, 6, 9};

Color c = {10, myRGB}; // This line doesn't work

return 0;
}


How can I initialize a Color object in one line?



In my real case scenario, Color struct can't be change (for example, to use std::array instead of a C-style array).










share|improve this question




















  • 4




    If you must use a variable for the initialization, then I suggest you create a constructor for the Color structure.
    – Some programmer dude
    Nov 5 at 14:38












  • @Someprogrammerdude OP says they can not add constructor, and there is a way to avoid the need for it.
    – SergeyA
    Nov 5 at 16:00










  • This code is a very wrong approach to C++ ... it is almost C98. The obvious thing to do is Color c = { 10, 2, 6, 9}
    – Chef Gladiator
    Nov 5 at 22:58















up vote
13
down vote

favorite
3












Consider the following code:



struct Color  // This struct can't be modified
{
double grey;
double rgb[3];
};

int main()
{
double myRGB[3] = {2, 6, 9};

Color c = {10, myRGB}; // This line doesn't work

return 0;
}


How can I initialize a Color object in one line?



In my real case scenario, Color struct can't be change (for example, to use std::array instead of a C-style array).










share|improve this question




















  • 4




    If you must use a variable for the initialization, then I suggest you create a constructor for the Color structure.
    – Some programmer dude
    Nov 5 at 14:38












  • @Someprogrammerdude OP says they can not add constructor, and there is a way to avoid the need for it.
    – SergeyA
    Nov 5 at 16:00










  • This code is a very wrong approach to C++ ... it is almost C98. The obvious thing to do is Color c = { 10, 2, 6, 9}
    – Chef Gladiator
    Nov 5 at 22:58













up vote
13
down vote

favorite
3









up vote
13
down vote

favorite
3






3





Consider the following code:



struct Color  // This struct can't be modified
{
double grey;
double rgb[3];
};

int main()
{
double myRGB[3] = {2, 6, 9};

Color c = {10, myRGB}; // This line doesn't work

return 0;
}


How can I initialize a Color object in one line?



In my real case scenario, Color struct can't be change (for example, to use std::array instead of a C-style array).










share|improve this question















Consider the following code:



struct Color  // This struct can't be modified
{
double grey;
double rgb[3];
};

int main()
{
double myRGB[3] = {2, 6, 9};

Color c = {10, myRGB}; // This line doesn't work

return 0;
}


How can I initialize a Color object in one line?



In my real case scenario, Color struct can't be change (for example, to use std::array instead of a C-style array).







c++ arrays constructor






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 5 at 21:06









Peter Mortensen

13.2k1983111




13.2k1983111










asked Nov 5 at 14:36









Gaetan

1496




1496








  • 4




    If you must use a variable for the initialization, then I suggest you create a constructor for the Color structure.
    – Some programmer dude
    Nov 5 at 14:38












  • @Someprogrammerdude OP says they can not add constructor, and there is a way to avoid the need for it.
    – SergeyA
    Nov 5 at 16:00










  • This code is a very wrong approach to C++ ... it is almost C98. The obvious thing to do is Color c = { 10, 2, 6, 9}
    – Chef Gladiator
    Nov 5 at 22:58














  • 4




    If you must use a variable for the initialization, then I suggest you create a constructor for the Color structure.
    – Some programmer dude
    Nov 5 at 14:38












  • @Someprogrammerdude OP says they can not add constructor, and there is a way to avoid the need for it.
    – SergeyA
    Nov 5 at 16:00










  • This code is a very wrong approach to C++ ... it is almost C98. The obvious thing to do is Color c = { 10, 2, 6, 9}
    – Chef Gladiator
    Nov 5 at 22:58








4




4




If you must use a variable for the initialization, then I suggest you create a constructor for the Color structure.
– Some programmer dude
Nov 5 at 14:38






If you must use a variable for the initialization, then I suggest you create a constructor for the Color structure.
– Some programmer dude
Nov 5 at 14:38














@Someprogrammerdude OP says they can not add constructor, and there is a way to avoid the need for it.
– SergeyA
Nov 5 at 16:00




@Someprogrammerdude OP says they can not add constructor, and there is a way to avoid the need for it.
– SergeyA
Nov 5 at 16:00












This code is a very wrong approach to C++ ... it is almost C98. The obvious thing to do is Color c = { 10, 2, 6, 9}
– Chef Gladiator
Nov 5 at 22:58




This code is a very wrong approach to C++ ... it is almost C98. The obvious thing to do is Color c = { 10, 2, 6, 9}
– Chef Gladiator
Nov 5 at 22:58












4 Answers
4






active

oldest

votes

















up vote
6
down vote



accepted










Supposing that there is a need to use an intermediate array, here is how one can do it:



#include <utility>
#include <cstddef>

struct Color //this struct can't be modified
{
double grey;
double rgb[3];
};

template<size_t N, size_t... IX>
auto make_c_impl(double grey, double (&rgb)[N], std::index_sequence<IX...>) {
static_assert(sizeof(rgb) == sizeof(Color::rgb), "Arrays sizes must match!");
return Color{grey, {rgb[IX]...}};
}

template<size_t N>
auto make_c(double grey, double (&rgb)[N]) {
return make_c_impl(grey, rgb, std::make_index_sequence<N>{});
}
double myRGB[3] = {2, 6, 9};

Color c = make_c(10, myRGB); //this line now works


Note, that this code will not actually produce any unnecessary copying with any level of optimization.






share|improve this answer























  • No need to make make_c a template: length of Color::rgb is known at compile time, so you can just use it (e.g. sizeof Color::rgb/sizeof*Color::rgb or, since C++17, std::size(decltype(Color::rgb){})).
    – Ruslan
    Nov 5 at 18:10












  • @Ruslan, yes, but than we wouldn't be able to present a nice message, and instead a substitute error would be displayed if sizes do not match
    – SergeyA
    Nov 5 at 19:01












  • With std::apply and std::experimental::to_array the definiton of make_c can be shortened to auto make_c = (double grey, auto&& rgb) { return std::apply([&](auto&&... args) { return Color{ grey, { args... } }; }, std::experimental::to_array(rgb)); but Color{ grey, { rgb[0], rgb[1], rgb[2] } } is still much simpler and easier to understand.
    – cpplearner
    Nov 5 at 19:40










  • @cpplearner I already argued that a wider-scoped answer is better than narrow-scoped, and manual indexing of elements is not scalable. to_array is a good suggestion.
    – SergeyA
    Nov 5 at 20:33










  • Both of you (SergeyA & NathanOliver ) have nice answers. As SergeA mentioned, a generic answers is most of the time expected. That was also my expectation when asking this question. However, when the generic answers become complicated it is nice to mention or illustrate how the problem can be solved in a simpler way as in the case of small array in NathanOliver answer. Thanks to both of you guys
    – Gaetan
    Nov 6 at 16:26


















up vote
18
down vote













Since Color is an aggregate you can use aggregate initialization and put the array initializer directly in the braces like



Color c = {10, {2, 6, 9}};




If you have to initialize c with an array, since it is small, you can just unroll it like



Color c = {10, {myRGB[0], myRGB[1], myRGB[2]}};





share|improve this answer



















  • 1




    I do not think it answers OP's question, looks like they need to initialize from a variable.
    – SergeyA
    Nov 5 at 15:31






  • 6




    @SergeyA ¯_(ツ)_/¯. The OP hasn't responded for me to know. I figured they used the array object because they didn't know they didn't need it. Hopefully they will respond at some point.
    – NathanOliver
    Nov 5 at 15:34








  • 10




    @SergeyA Because your answer is half a screen filled with template noise?
    – pipe
    Nov 5 at 16:14






  • 5




    @SergeyA No, I'm saying (and the author of this answer) that sometimes manual repetition is perfectly fine, easier to understand and easier to maintain.
    – pipe
    Nov 5 at 16:16






  • 2




    @pipe I believe a generic question is more important than the specific one - how do you initialize one C-style array from another. Future readers are less likely to benefit from the narrow answer than from the the wider scope one.
    – SergeyA
    Nov 5 at 16:27


















up vote
4
down vote













As complement to others answers, the error is because in c++ arrays are not copyable and trying to initialize an array from an lvalue has the semantic of invoking the copy-constructor, the same as:



double r1[3] = {0., 0., 0.};
double r2[3] {r1} // doesn't compile


Your options are:




  • do list-initialization as @NathanOliver did

  • or expand the elements of the array to form a list-initialization as in the @SergeyA answer.






share|improve this answer






























    up vote
    1
    down vote













    Call me a cheat, but...



     struct Color final  
    {
    double grey;
    double rgb[3];
    };
    // the cheet
    #define make_color( x, a, b ) Color x { a, b[0], b[1], b[2] }

    int main()
    {
    double myRGB[3]{ 2, 6, 9 };

    make_color( c, 10, myRGB ) ; // single line construction

    printf("nColor grey: %ft rgb:[ %f, %f, %f ]", c.grey, c.rgb[0], c.rgb[1], c.rgb[2] ) ;
    }


    But, since that is pretty atrocious C++, I have taken a liberty of producing something slightly better...



    struct Color final  
    {
    double grey;
    double rgb[3];
    };

    auto make_color ( double a, const double(&b)[3] ) { return Color { a, b[0], b[1], b[2] }; };
    auto make_color ( double a, double b, double c, double d ) { return Color { a, b, c, d }; };
    auto print_color ( Color c ) { printf("nColor grey: %ft rgb:[ %f, %f, %f ]", c.grey, c.rgb[0], c.rgb[1], c.rgb[2] ) ; }
    //
    int main()
    {
    double myRGB[3]{ 2, 6, 9 };

    auto c = make_color( 10, myRGB ) ;
    print_color(c);
    auto z = make_color( 10, 0xFF, 0xA0, 0xB0 ) ;
    print_color(z);

    }


    All in a good old SO tradition: do not question the question :)



    (the mandatory Wandbox is here)



    ps: I like your approach Oliver, although you do not need double braces in those init lists, of course.






    share|improve this answer





















      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














       

      draft saved


      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53156499%2finitialize-object-containing-c-style-array-as-member-variable-c%23new-answer', 'question_page');
      }
      );

      Post as a guest
































      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      6
      down vote



      accepted










      Supposing that there is a need to use an intermediate array, here is how one can do it:



      #include <utility>
      #include <cstddef>

      struct Color //this struct can't be modified
      {
      double grey;
      double rgb[3];
      };

      template<size_t N, size_t... IX>
      auto make_c_impl(double grey, double (&rgb)[N], std::index_sequence<IX...>) {
      static_assert(sizeof(rgb) == sizeof(Color::rgb), "Arrays sizes must match!");
      return Color{grey, {rgb[IX]...}};
      }

      template<size_t N>
      auto make_c(double grey, double (&rgb)[N]) {
      return make_c_impl(grey, rgb, std::make_index_sequence<N>{});
      }
      double myRGB[3] = {2, 6, 9};

      Color c = make_c(10, myRGB); //this line now works


      Note, that this code will not actually produce any unnecessary copying with any level of optimization.






      share|improve this answer























      • No need to make make_c a template: length of Color::rgb is known at compile time, so you can just use it (e.g. sizeof Color::rgb/sizeof*Color::rgb or, since C++17, std::size(decltype(Color::rgb){})).
        – Ruslan
        Nov 5 at 18:10












      • @Ruslan, yes, but than we wouldn't be able to present a nice message, and instead a substitute error would be displayed if sizes do not match
        – SergeyA
        Nov 5 at 19:01












      • With std::apply and std::experimental::to_array the definiton of make_c can be shortened to auto make_c = (double grey, auto&& rgb) { return std::apply([&](auto&&... args) { return Color{ grey, { args... } }; }, std::experimental::to_array(rgb)); but Color{ grey, { rgb[0], rgb[1], rgb[2] } } is still much simpler and easier to understand.
        – cpplearner
        Nov 5 at 19:40










      • @cpplearner I already argued that a wider-scoped answer is better than narrow-scoped, and manual indexing of elements is not scalable. to_array is a good suggestion.
        – SergeyA
        Nov 5 at 20:33










      • Both of you (SergeyA & NathanOliver ) have nice answers. As SergeA mentioned, a generic answers is most of the time expected. That was also my expectation when asking this question. However, when the generic answers become complicated it is nice to mention or illustrate how the problem can be solved in a simpler way as in the case of small array in NathanOliver answer. Thanks to both of you guys
        – Gaetan
        Nov 6 at 16:26















      up vote
      6
      down vote



      accepted










      Supposing that there is a need to use an intermediate array, here is how one can do it:



      #include <utility>
      #include <cstddef>

      struct Color //this struct can't be modified
      {
      double grey;
      double rgb[3];
      };

      template<size_t N, size_t... IX>
      auto make_c_impl(double grey, double (&rgb)[N], std::index_sequence<IX...>) {
      static_assert(sizeof(rgb) == sizeof(Color::rgb), "Arrays sizes must match!");
      return Color{grey, {rgb[IX]...}};
      }

      template<size_t N>
      auto make_c(double grey, double (&rgb)[N]) {
      return make_c_impl(grey, rgb, std::make_index_sequence<N>{});
      }
      double myRGB[3] = {2, 6, 9};

      Color c = make_c(10, myRGB); //this line now works


      Note, that this code will not actually produce any unnecessary copying with any level of optimization.






      share|improve this answer























      • No need to make make_c a template: length of Color::rgb is known at compile time, so you can just use it (e.g. sizeof Color::rgb/sizeof*Color::rgb or, since C++17, std::size(decltype(Color::rgb){})).
        – Ruslan
        Nov 5 at 18:10












      • @Ruslan, yes, but than we wouldn't be able to present a nice message, and instead a substitute error would be displayed if sizes do not match
        – SergeyA
        Nov 5 at 19:01












      • With std::apply and std::experimental::to_array the definiton of make_c can be shortened to auto make_c = (double grey, auto&& rgb) { return std::apply([&](auto&&... args) { return Color{ grey, { args... } }; }, std::experimental::to_array(rgb)); but Color{ grey, { rgb[0], rgb[1], rgb[2] } } is still much simpler and easier to understand.
        – cpplearner
        Nov 5 at 19:40










      • @cpplearner I already argued that a wider-scoped answer is better than narrow-scoped, and manual indexing of elements is not scalable. to_array is a good suggestion.
        – SergeyA
        Nov 5 at 20:33










      • Both of you (SergeyA & NathanOliver ) have nice answers. As SergeA mentioned, a generic answers is most of the time expected. That was also my expectation when asking this question. However, when the generic answers become complicated it is nice to mention or illustrate how the problem can be solved in a simpler way as in the case of small array in NathanOliver answer. Thanks to both of you guys
        – Gaetan
        Nov 6 at 16:26













      up vote
      6
      down vote



      accepted







      up vote
      6
      down vote



      accepted






      Supposing that there is a need to use an intermediate array, here is how one can do it:



      #include <utility>
      #include <cstddef>

      struct Color //this struct can't be modified
      {
      double grey;
      double rgb[3];
      };

      template<size_t N, size_t... IX>
      auto make_c_impl(double grey, double (&rgb)[N], std::index_sequence<IX...>) {
      static_assert(sizeof(rgb) == sizeof(Color::rgb), "Arrays sizes must match!");
      return Color{grey, {rgb[IX]...}};
      }

      template<size_t N>
      auto make_c(double grey, double (&rgb)[N]) {
      return make_c_impl(grey, rgb, std::make_index_sequence<N>{});
      }
      double myRGB[3] = {2, 6, 9};

      Color c = make_c(10, myRGB); //this line now works


      Note, that this code will not actually produce any unnecessary copying with any level of optimization.






      share|improve this answer














      Supposing that there is a need to use an intermediate array, here is how one can do it:



      #include <utility>
      #include <cstddef>

      struct Color //this struct can't be modified
      {
      double grey;
      double rgb[3];
      };

      template<size_t N, size_t... IX>
      auto make_c_impl(double grey, double (&rgb)[N], std::index_sequence<IX...>) {
      static_assert(sizeof(rgb) == sizeof(Color::rgb), "Arrays sizes must match!");
      return Color{grey, {rgb[IX]...}};
      }

      template<size_t N>
      auto make_c(double grey, double (&rgb)[N]) {
      return make_c_impl(grey, rgb, std::make_index_sequence<N>{});
      }
      double myRGB[3] = {2, 6, 9};

      Color c = make_c(10, myRGB); //this line now works


      Note, that this code will not actually produce any unnecessary copying with any level of optimization.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 5 at 16:48

























      answered Nov 5 at 15:57









      SergeyA

      39.3k53579




      39.3k53579












      • No need to make make_c a template: length of Color::rgb is known at compile time, so you can just use it (e.g. sizeof Color::rgb/sizeof*Color::rgb or, since C++17, std::size(decltype(Color::rgb){})).
        – Ruslan
        Nov 5 at 18:10












      • @Ruslan, yes, but than we wouldn't be able to present a nice message, and instead a substitute error would be displayed if sizes do not match
        – SergeyA
        Nov 5 at 19:01












      • With std::apply and std::experimental::to_array the definiton of make_c can be shortened to auto make_c = (double grey, auto&& rgb) { return std::apply([&](auto&&... args) { return Color{ grey, { args... } }; }, std::experimental::to_array(rgb)); but Color{ grey, { rgb[0], rgb[1], rgb[2] } } is still much simpler and easier to understand.
        – cpplearner
        Nov 5 at 19:40










      • @cpplearner I already argued that a wider-scoped answer is better than narrow-scoped, and manual indexing of elements is not scalable. to_array is a good suggestion.
        – SergeyA
        Nov 5 at 20:33










      • Both of you (SergeyA & NathanOliver ) have nice answers. As SergeA mentioned, a generic answers is most of the time expected. That was also my expectation when asking this question. However, when the generic answers become complicated it is nice to mention or illustrate how the problem can be solved in a simpler way as in the case of small array in NathanOliver answer. Thanks to both of you guys
        – Gaetan
        Nov 6 at 16:26


















      • No need to make make_c a template: length of Color::rgb is known at compile time, so you can just use it (e.g. sizeof Color::rgb/sizeof*Color::rgb or, since C++17, std::size(decltype(Color::rgb){})).
        – Ruslan
        Nov 5 at 18:10












      • @Ruslan, yes, but than we wouldn't be able to present a nice message, and instead a substitute error would be displayed if sizes do not match
        – SergeyA
        Nov 5 at 19:01












      • With std::apply and std::experimental::to_array the definiton of make_c can be shortened to auto make_c = (double grey, auto&& rgb) { return std::apply([&](auto&&... args) { return Color{ grey, { args... } }; }, std::experimental::to_array(rgb)); but Color{ grey, { rgb[0], rgb[1], rgb[2] } } is still much simpler and easier to understand.
        – cpplearner
        Nov 5 at 19:40










      • @cpplearner I already argued that a wider-scoped answer is better than narrow-scoped, and manual indexing of elements is not scalable. to_array is a good suggestion.
        – SergeyA
        Nov 5 at 20:33










      • Both of you (SergeyA & NathanOliver ) have nice answers. As SergeA mentioned, a generic answers is most of the time expected. That was also my expectation when asking this question. However, when the generic answers become complicated it is nice to mention or illustrate how the problem can be solved in a simpler way as in the case of small array in NathanOliver answer. Thanks to both of you guys
        – Gaetan
        Nov 6 at 16:26
















      No need to make make_c a template: length of Color::rgb is known at compile time, so you can just use it (e.g. sizeof Color::rgb/sizeof*Color::rgb or, since C++17, std::size(decltype(Color::rgb){})).
      – Ruslan
      Nov 5 at 18:10






      No need to make make_c a template: length of Color::rgb is known at compile time, so you can just use it (e.g. sizeof Color::rgb/sizeof*Color::rgb or, since C++17, std::size(decltype(Color::rgb){})).
      – Ruslan
      Nov 5 at 18:10














      @Ruslan, yes, but than we wouldn't be able to present a nice message, and instead a substitute error would be displayed if sizes do not match
      – SergeyA
      Nov 5 at 19:01






      @Ruslan, yes, but than we wouldn't be able to present a nice message, and instead a substitute error would be displayed if sizes do not match
      – SergeyA
      Nov 5 at 19:01














      With std::apply and std::experimental::to_array the definiton of make_c can be shortened to auto make_c = (double grey, auto&& rgb) { return std::apply([&](auto&&... args) { return Color{ grey, { args... } }; }, std::experimental::to_array(rgb)); but Color{ grey, { rgb[0], rgb[1], rgb[2] } } is still much simpler and easier to understand.
      – cpplearner
      Nov 5 at 19:40




      With std::apply and std::experimental::to_array the definiton of make_c can be shortened to auto make_c = (double grey, auto&& rgb) { return std::apply([&](auto&&... args) { return Color{ grey, { args... } }; }, std::experimental::to_array(rgb)); but Color{ grey, { rgb[0], rgb[1], rgb[2] } } is still much simpler and easier to understand.
      – cpplearner
      Nov 5 at 19:40












      @cpplearner I already argued that a wider-scoped answer is better than narrow-scoped, and manual indexing of elements is not scalable. to_array is a good suggestion.
      – SergeyA
      Nov 5 at 20:33




      @cpplearner I already argued that a wider-scoped answer is better than narrow-scoped, and manual indexing of elements is not scalable. to_array is a good suggestion.
      – SergeyA
      Nov 5 at 20:33












      Both of you (SergeyA & NathanOliver ) have nice answers. As SergeA mentioned, a generic answers is most of the time expected. That was also my expectation when asking this question. However, when the generic answers become complicated it is nice to mention or illustrate how the problem can be solved in a simpler way as in the case of small array in NathanOliver answer. Thanks to both of you guys
      – Gaetan
      Nov 6 at 16:26




      Both of you (SergeyA & NathanOliver ) have nice answers. As SergeA mentioned, a generic answers is most of the time expected. That was also my expectation when asking this question. However, when the generic answers become complicated it is nice to mention or illustrate how the problem can be solved in a simpler way as in the case of small array in NathanOliver answer. Thanks to both of you guys
      – Gaetan
      Nov 6 at 16:26












      up vote
      18
      down vote













      Since Color is an aggregate you can use aggregate initialization and put the array initializer directly in the braces like



      Color c = {10, {2, 6, 9}};




      If you have to initialize c with an array, since it is small, you can just unroll it like



      Color c = {10, {myRGB[0], myRGB[1], myRGB[2]}};





      share|improve this answer



















      • 1




        I do not think it answers OP's question, looks like they need to initialize from a variable.
        – SergeyA
        Nov 5 at 15:31






      • 6




        @SergeyA ¯_(ツ)_/¯. The OP hasn't responded for me to know. I figured they used the array object because they didn't know they didn't need it. Hopefully they will respond at some point.
        – NathanOliver
        Nov 5 at 15:34








      • 10




        @SergeyA Because your answer is half a screen filled with template noise?
        – pipe
        Nov 5 at 16:14






      • 5




        @SergeyA No, I'm saying (and the author of this answer) that sometimes manual repetition is perfectly fine, easier to understand and easier to maintain.
        – pipe
        Nov 5 at 16:16






      • 2




        @pipe I believe a generic question is more important than the specific one - how do you initialize one C-style array from another. Future readers are less likely to benefit from the narrow answer than from the the wider scope one.
        – SergeyA
        Nov 5 at 16:27















      up vote
      18
      down vote













      Since Color is an aggregate you can use aggregate initialization and put the array initializer directly in the braces like



      Color c = {10, {2, 6, 9}};




      If you have to initialize c with an array, since it is small, you can just unroll it like



      Color c = {10, {myRGB[0], myRGB[1], myRGB[2]}};





      share|improve this answer



















      • 1




        I do not think it answers OP's question, looks like they need to initialize from a variable.
        – SergeyA
        Nov 5 at 15:31






      • 6




        @SergeyA ¯_(ツ)_/¯. The OP hasn't responded for me to know. I figured they used the array object because they didn't know they didn't need it. Hopefully they will respond at some point.
        – NathanOliver
        Nov 5 at 15:34








      • 10




        @SergeyA Because your answer is half a screen filled with template noise?
        – pipe
        Nov 5 at 16:14






      • 5




        @SergeyA No, I'm saying (and the author of this answer) that sometimes manual repetition is perfectly fine, easier to understand and easier to maintain.
        – pipe
        Nov 5 at 16:16






      • 2




        @pipe I believe a generic question is more important than the specific one - how do you initialize one C-style array from another. Future readers are less likely to benefit from the narrow answer than from the the wider scope one.
        – SergeyA
        Nov 5 at 16:27













      up vote
      18
      down vote










      up vote
      18
      down vote









      Since Color is an aggregate you can use aggregate initialization and put the array initializer directly in the braces like



      Color c = {10, {2, 6, 9}};




      If you have to initialize c with an array, since it is small, you can just unroll it like



      Color c = {10, {myRGB[0], myRGB[1], myRGB[2]}};





      share|improve this answer














      Since Color is an aggregate you can use aggregate initialization and put the array initializer directly in the braces like



      Color c = {10, {2, 6, 9}};




      If you have to initialize c with an array, since it is small, you can just unroll it like



      Color c = {10, {myRGB[0], myRGB[1], myRGB[2]}};






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 5 at 15:48

























      answered Nov 5 at 14:38









      NathanOliver

      81.7k15111172




      81.7k15111172








      • 1




        I do not think it answers OP's question, looks like they need to initialize from a variable.
        – SergeyA
        Nov 5 at 15:31






      • 6




        @SergeyA ¯_(ツ)_/¯. The OP hasn't responded for me to know. I figured they used the array object because they didn't know they didn't need it. Hopefully they will respond at some point.
        – NathanOliver
        Nov 5 at 15:34








      • 10




        @SergeyA Because your answer is half a screen filled with template noise?
        – pipe
        Nov 5 at 16:14






      • 5




        @SergeyA No, I'm saying (and the author of this answer) that sometimes manual repetition is perfectly fine, easier to understand and easier to maintain.
        – pipe
        Nov 5 at 16:16






      • 2




        @pipe I believe a generic question is more important than the specific one - how do you initialize one C-style array from another. Future readers are less likely to benefit from the narrow answer than from the the wider scope one.
        – SergeyA
        Nov 5 at 16:27














      • 1




        I do not think it answers OP's question, looks like they need to initialize from a variable.
        – SergeyA
        Nov 5 at 15:31






      • 6




        @SergeyA ¯_(ツ)_/¯. The OP hasn't responded for me to know. I figured they used the array object because they didn't know they didn't need it. Hopefully they will respond at some point.
        – NathanOliver
        Nov 5 at 15:34








      • 10




        @SergeyA Because your answer is half a screen filled with template noise?
        – pipe
        Nov 5 at 16:14






      • 5




        @SergeyA No, I'm saying (and the author of this answer) that sometimes manual repetition is perfectly fine, easier to understand and easier to maintain.
        – pipe
        Nov 5 at 16:16






      • 2




        @pipe I believe a generic question is more important than the specific one - how do you initialize one C-style array from another. Future readers are less likely to benefit from the narrow answer than from the the wider scope one.
        – SergeyA
        Nov 5 at 16:27








      1




      1




      I do not think it answers OP's question, looks like they need to initialize from a variable.
      – SergeyA
      Nov 5 at 15:31




      I do not think it answers OP's question, looks like they need to initialize from a variable.
      – SergeyA
      Nov 5 at 15:31




      6




      6




      @SergeyA ¯_(ツ)_/¯. The OP hasn't responded for me to know. I figured they used the array object because they didn't know they didn't need it. Hopefully they will respond at some point.
      – NathanOliver
      Nov 5 at 15:34






      @SergeyA ¯_(ツ)_/¯. The OP hasn't responded for me to know. I figured they used the array object because they didn't know they didn't need it. Hopefully they will respond at some point.
      – NathanOliver
      Nov 5 at 15:34






      10




      10




      @SergeyA Because your answer is half a screen filled with template noise?
      – pipe
      Nov 5 at 16:14




      @SergeyA Because your answer is half a screen filled with template noise?
      – pipe
      Nov 5 at 16:14




      5




      5




      @SergeyA No, I'm saying (and the author of this answer) that sometimes manual repetition is perfectly fine, easier to understand and easier to maintain.
      – pipe
      Nov 5 at 16:16




      @SergeyA No, I'm saying (and the author of this answer) that sometimes manual repetition is perfectly fine, easier to understand and easier to maintain.
      – pipe
      Nov 5 at 16:16




      2




      2




      @pipe I believe a generic question is more important than the specific one - how do you initialize one C-style array from another. Future readers are less likely to benefit from the narrow answer than from the the wider scope one.
      – SergeyA
      Nov 5 at 16:27




      @pipe I believe a generic question is more important than the specific one - how do you initialize one C-style array from another. Future readers are less likely to benefit from the narrow answer than from the the wider scope one.
      – SergeyA
      Nov 5 at 16:27










      up vote
      4
      down vote













      As complement to others answers, the error is because in c++ arrays are not copyable and trying to initialize an array from an lvalue has the semantic of invoking the copy-constructor, the same as:



      double r1[3] = {0., 0., 0.};
      double r2[3] {r1} // doesn't compile


      Your options are:




      • do list-initialization as @NathanOliver did

      • or expand the elements of the array to form a list-initialization as in the @SergeyA answer.






      share|improve this answer



























        up vote
        4
        down vote













        As complement to others answers, the error is because in c++ arrays are not copyable and trying to initialize an array from an lvalue has the semantic of invoking the copy-constructor, the same as:



        double r1[3] = {0., 0., 0.};
        double r2[3] {r1} // doesn't compile


        Your options are:




        • do list-initialization as @NathanOliver did

        • or expand the elements of the array to form a list-initialization as in the @SergeyA answer.






        share|improve this answer

























          up vote
          4
          down vote










          up vote
          4
          down vote









          As complement to others answers, the error is because in c++ arrays are not copyable and trying to initialize an array from an lvalue has the semantic of invoking the copy-constructor, the same as:



          double r1[3] = {0., 0., 0.};
          double r2[3] {r1} // doesn't compile


          Your options are:




          • do list-initialization as @NathanOliver did

          • or expand the elements of the array to form a list-initialization as in the @SergeyA answer.






          share|improve this answer














          As complement to others answers, the error is because in c++ arrays are not copyable and trying to initialize an array from an lvalue has the semantic of invoking the copy-constructor, the same as:



          double r1[3] = {0., 0., 0.};
          double r2[3] {r1} // doesn't compile


          Your options are:




          • do list-initialization as @NathanOliver did

          • or expand the elements of the array to form a list-initialization as in the @SergeyA answer.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 6 at 1:57

























          answered Nov 5 at 16:08









          Jans

          5,57111928




          5,57111928






















              up vote
              1
              down vote













              Call me a cheat, but...



               struct Color final  
              {
              double grey;
              double rgb[3];
              };
              // the cheet
              #define make_color( x, a, b ) Color x { a, b[0], b[1], b[2] }

              int main()
              {
              double myRGB[3]{ 2, 6, 9 };

              make_color( c, 10, myRGB ) ; // single line construction

              printf("nColor grey: %ft rgb:[ %f, %f, %f ]", c.grey, c.rgb[0], c.rgb[1], c.rgb[2] ) ;
              }


              But, since that is pretty atrocious C++, I have taken a liberty of producing something slightly better...



              struct Color final  
              {
              double grey;
              double rgb[3];
              };

              auto make_color ( double a, const double(&b)[3] ) { return Color { a, b[0], b[1], b[2] }; };
              auto make_color ( double a, double b, double c, double d ) { return Color { a, b, c, d }; };
              auto print_color ( Color c ) { printf("nColor grey: %ft rgb:[ %f, %f, %f ]", c.grey, c.rgb[0], c.rgb[1], c.rgb[2] ) ; }
              //
              int main()
              {
              double myRGB[3]{ 2, 6, 9 };

              auto c = make_color( 10, myRGB ) ;
              print_color(c);
              auto z = make_color( 10, 0xFF, 0xA0, 0xB0 ) ;
              print_color(z);

              }


              All in a good old SO tradition: do not question the question :)



              (the mandatory Wandbox is here)



              ps: I like your approach Oliver, although you do not need double braces in those init lists, of course.






              share|improve this answer

























                up vote
                1
                down vote













                Call me a cheat, but...



                 struct Color final  
                {
                double grey;
                double rgb[3];
                };
                // the cheet
                #define make_color( x, a, b ) Color x { a, b[0], b[1], b[2] }

                int main()
                {
                double myRGB[3]{ 2, 6, 9 };

                make_color( c, 10, myRGB ) ; // single line construction

                printf("nColor grey: %ft rgb:[ %f, %f, %f ]", c.grey, c.rgb[0], c.rgb[1], c.rgb[2] ) ;
                }


                But, since that is pretty atrocious C++, I have taken a liberty of producing something slightly better...



                struct Color final  
                {
                double grey;
                double rgb[3];
                };

                auto make_color ( double a, const double(&b)[3] ) { return Color { a, b[0], b[1], b[2] }; };
                auto make_color ( double a, double b, double c, double d ) { return Color { a, b, c, d }; };
                auto print_color ( Color c ) { printf("nColor grey: %ft rgb:[ %f, %f, %f ]", c.grey, c.rgb[0], c.rgb[1], c.rgb[2] ) ; }
                //
                int main()
                {
                double myRGB[3]{ 2, 6, 9 };

                auto c = make_color( 10, myRGB ) ;
                print_color(c);
                auto z = make_color( 10, 0xFF, 0xA0, 0xB0 ) ;
                print_color(z);

                }


                All in a good old SO tradition: do not question the question :)



                (the mandatory Wandbox is here)



                ps: I like your approach Oliver, although you do not need double braces in those init lists, of course.






                share|improve this answer























                  up vote
                  1
                  down vote










                  up vote
                  1
                  down vote









                  Call me a cheat, but...



                   struct Color final  
                  {
                  double grey;
                  double rgb[3];
                  };
                  // the cheet
                  #define make_color( x, a, b ) Color x { a, b[0], b[1], b[2] }

                  int main()
                  {
                  double myRGB[3]{ 2, 6, 9 };

                  make_color( c, 10, myRGB ) ; // single line construction

                  printf("nColor grey: %ft rgb:[ %f, %f, %f ]", c.grey, c.rgb[0], c.rgb[1], c.rgb[2] ) ;
                  }


                  But, since that is pretty atrocious C++, I have taken a liberty of producing something slightly better...



                  struct Color final  
                  {
                  double grey;
                  double rgb[3];
                  };

                  auto make_color ( double a, const double(&b)[3] ) { return Color { a, b[0], b[1], b[2] }; };
                  auto make_color ( double a, double b, double c, double d ) { return Color { a, b, c, d }; };
                  auto print_color ( Color c ) { printf("nColor grey: %ft rgb:[ %f, %f, %f ]", c.grey, c.rgb[0], c.rgb[1], c.rgb[2] ) ; }
                  //
                  int main()
                  {
                  double myRGB[3]{ 2, 6, 9 };

                  auto c = make_color( 10, myRGB ) ;
                  print_color(c);
                  auto z = make_color( 10, 0xFF, 0xA0, 0xB0 ) ;
                  print_color(z);

                  }


                  All in a good old SO tradition: do not question the question :)



                  (the mandatory Wandbox is here)



                  ps: I like your approach Oliver, although you do not need double braces in those init lists, of course.






                  share|improve this answer












                  Call me a cheat, but...



                   struct Color final  
                  {
                  double grey;
                  double rgb[3];
                  };
                  // the cheet
                  #define make_color( x, a, b ) Color x { a, b[0], b[1], b[2] }

                  int main()
                  {
                  double myRGB[3]{ 2, 6, 9 };

                  make_color( c, 10, myRGB ) ; // single line construction

                  printf("nColor grey: %ft rgb:[ %f, %f, %f ]", c.grey, c.rgb[0], c.rgb[1], c.rgb[2] ) ;
                  }


                  But, since that is pretty atrocious C++, I have taken a liberty of producing something slightly better...



                  struct Color final  
                  {
                  double grey;
                  double rgb[3];
                  };

                  auto make_color ( double a, const double(&b)[3] ) { return Color { a, b[0], b[1], b[2] }; };
                  auto make_color ( double a, double b, double c, double d ) { return Color { a, b, c, d }; };
                  auto print_color ( Color c ) { printf("nColor grey: %ft rgb:[ %f, %f, %f ]", c.grey, c.rgb[0], c.rgb[1], c.rgb[2] ) ; }
                  //
                  int main()
                  {
                  double myRGB[3]{ 2, 6, 9 };

                  auto c = make_color( 10, myRGB ) ;
                  print_color(c);
                  auto z = make_color( 10, 0xFF, 0xA0, 0xB0 ) ;
                  print_color(z);

                  }


                  All in a good old SO tradition: do not question the question :)



                  (the mandatory Wandbox is here)



                  ps: I like your approach Oliver, although you do not need double braces in those init lists, of course.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 5 at 22:39









                  Chef Gladiator

                  149110




                  149110






























                       

                      draft saved


                      draft discarded



















































                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53156499%2finitialize-object-containing-c-style-array-as-member-variable-c%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest




















































































                      這個網誌中的熱門文章

                      Tangent Lines Diagram Along Smooth Curve

                      Yusuf al-Mu'taman ibn Hud

                      Zucchini