-2

Let's say there's a struct type that will be used used to hold the coordinates of a Point in 3D space.

This could be defined like:

struct Point { double x, y, z; };

Making use of double values because we want to be as precise as possible.

An instance of this struct, could be declared using designated compound literals, like:

double x = 0.0;
double y = 0.0;
double z = 0.0;
...
Point p = (struct Point){ .x=x, .y=y, .z=z };

However, when trying to declare another Point starting from different types:

int x = 0;
int y = 0;
int z = 0;
...
Point p = (struct Point){ .x=x, .y=y, .z=z };

The compiler throws an error, because it's unable to find a suitable constructor. This works if one does:

Point p = (struct Point){ .x=(double)x, .y=(double)y, .z=(double)z };

Is there a way to overload the Point constructor, so that one does not have to manually cast each member of the initializer list to double?

Perhaps using something like Point(initializer_list<int> ...) {} in the struct's declaration?

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
Ale Morales
  • 2,728
  • 4
  • 29
  • 42
  • 3
    I think that the `{ .x=x, .y=y, .z=z }` syntax is from C, not C++, isn't it? – yeputons Feb 22 '17 at 01:02
  • Yes, but constructors/overloading belongs to C++, unless I'm out of date. – Ale Morales Feb 22 '17 at 01:03
  • I would just make a `std::initializer_list` constructor. – NathanOliver Feb 22 '17 at 01:04
  • 1
    That sounds good. Care to share how? – Ale Morales Feb 22 '17 at 01:05
  • Are you okay with a C++11 or above answer? – NathanOliver Feb 22 '17 at 01:10
  • Absolutely. "4 more characters to go" – Ale Morales Feb 22 '17 at 01:11
  • 2
    @almosnow Looks like C++11 does not support designated initializers at all: see [here](http://stackoverflow.com/questions/18731707/why-does-c11-not-support-designated-initializer-list-as-c99) and [there](http://stackoverflow.com/questions/10859213/what-is-the-c-equivalent-to-cs-designated-initializers), so I doubt it's possible to overload them. Anyway, would be happy to learn otherwise. – yeputons Feb 22 '17 at 01:11
  • @yeputons Wow, didn't knew that... that's kind of lame. I always thought of C++ as being some kind of superset of C. – Ale Morales Feb 22 '17 at 01:14
  • Also, compiles fine in clang. – Ale Morales Feb 22 '17 at 01:18
  • @almosnow That is a compiler extension. Nothing forbids them from adding it you just have to know that it reduces the portability of the code. – NathanOliver Feb 22 '17 at 01:22
  • 1
    @almosnow: C and C++ are distinct languages, none is a superset of the other. Even identical syntax does not imply identical semantics. That's why double-tagging for both is not well received here. To be clear: don't add a C tag for C++ questions and vice-versa! – too honest for this site Feb 22 '17 at 01:25
  • *That's why double-tagging for both is not well received here.* Yeah no, it is completely justified. It actually applies to **both** languages. Not really in a mood to argue, see you around. – Ale Morales Feb 22 '17 at 01:26

1 Answers1

3

You are not doing to be able to overload the designated initializer list as that is not a supported C++ feature but by using a constructor and C++11's uniform initialization you can get pretty close to what you want. If we have

struct Point { 
    Point (double x, double y, double z) : x(x), y(y), z(z) {}
    double x, y, z; 
};

Then we can use it like

int main() {
    double x = 0.0;
    double y = 0.0;
    double z = 0.0;

    Point p{x, y, z};
    Point i{1, 2, 3};
}
Community
  • 1
  • 1
NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • 1
    @almosnow: It's already [voted in for C++20, apparently](https://botondballo.wordpress.com/2016/07/06/trip-report-c-standards-meeting-in-oulu-june-2016/). With some limitations, relative to C. – Nicol Bolas Feb 22 '17 at 02:42