Initialize object containing C-style array as member variable (C++)
up vote
13
down vote
favorite
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
add a comment |
up vote
13
down vote
favorite
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
4
If you must use a variable for the initialization, then I suggest you create a constructor for theColor
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 isColor c = { 10, 2, 6, 9}
– Chef Gladiator
Nov 5 at 22:58
add a comment |
up vote
13
down vote
favorite
up vote
13
down vote
favorite
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
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
c++ arrays constructor
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 theColor
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 isColor c = { 10, 2, 6, 9}
– Chef Gladiator
Nov 5 at 22:58
add a comment |
4
If you must use a variable for the initialization, then I suggest you create a constructor for theColor
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 isColor 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
add a comment |
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.
No need to makemake_c
a template: length ofColor::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
Withstd::apply
andstd::experimental::to_array
the definiton ofmake_c
can be shortened toauto make_c = (double grey, auto&& rgb) { return std::apply([&](auto&&... args) { return Color{ grey, { args... } }; }, std::experimental::to_array(rgb));
butColor{ 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
add a comment |
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]}};
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
|
show 6 more comments
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.
add a comment |
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.
add a comment |
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.
No need to makemake_c
a template: length ofColor::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
Withstd::apply
andstd::experimental::to_array
the definiton ofmake_c
can be shortened toauto make_c = (double grey, auto&& rgb) { return std::apply([&](auto&&... args) { return Color{ grey, { args... } }; }, std::experimental::to_array(rgb));
butColor{ 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
add a comment |
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.
No need to makemake_c
a template: length ofColor::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
Withstd::apply
andstd::experimental::to_array
the definiton ofmake_c
can be shortened toauto make_c = (double grey, auto&& rgb) { return std::apply([&](auto&&... args) { return Color{ grey, { args... } }; }, std::experimental::to_array(rgb));
butColor{ 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
add a comment |
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.
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.
edited Nov 5 at 16:48
answered Nov 5 at 15:57
SergeyA
39.3k53579
39.3k53579
No need to makemake_c
a template: length ofColor::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
Withstd::apply
andstd::experimental::to_array
the definiton ofmake_c
can be shortened toauto make_c = (double grey, auto&& rgb) { return std::apply([&](auto&&... args) { return Color{ grey, { args... } }; }, std::experimental::to_array(rgb));
butColor{ 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
add a comment |
No need to makemake_c
a template: length ofColor::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
Withstd::apply
andstd::experimental::to_array
the definiton ofmake_c
can be shortened toauto make_c = (double grey, auto&& rgb) { return std::apply([&](auto&&... args) { return Color{ grey, { args... } }; }, std::experimental::to_array(rgb));
butColor{ 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
add a comment |
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]}};
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
|
show 6 more comments
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]}};
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
|
show 6 more comments
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]}};
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]}};
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
|
show 6 more comments
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
|
show 6 more comments
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.
add a comment |
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.
add a comment |
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.
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.
edited Nov 6 at 1:57
answered Nov 5 at 16:08
Jans
5,57111928
5,57111928
add a comment |
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 5 at 22:39
Chef Gladiator
149110
149110
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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