Как построить точку по указателю в одну строку?

0

У меня есть конструктор Point, который принимает двойной указатель. Я делаю это следующим образом

Point::Point(double* p)
   : mX(p[0]), mY(p[1]), mZ(p[2])
{}

Point pt( []() -> double* {double p[3] = {1, 2, 3}; return p;}() );

Любой более простой способ построить указатель в одной строке с указанными значениями?

Теги:
c++11

3 ответа

4
Лучший ответ

Самый простой способ сделать это - объявить локальный массив и передать указатель на это:

double p[3] = {1, 2, 3};
Point pt(p);

В качестве альтернативы рассмотрим возможность написания нового конструктора, который позволяет напрямую передать три координаты:

Point::Point(double x, double y, double z)
    : mX(x), mY(y), mZ(z)
{ }

Если добавить конструктор невозможно, вы можете использовать фабрику:

Point make_point(double x, double y, double z)
{
    double p[3] = { x, y, z };

    return Point(p);
}
  • 0
    Хорошая идея и легко читается.
3

[EDIT] Это создает временный массив в стеке, поэтому будет намного быстрее, чем два других варианта, которые включают выделение памяти (new/delete):

Point pt( &(double[3]){1, 2, 3}[0] );

Чтобы избежать утечки памяти и фактически вернуть указатель, вы должны сделать это несколько дольше:

Point pt( std::unique_ptr<double>(
    []() -> double* { return new double[3]{1, 2, 3}; }()
    ).get() );

Другой вариант:

Point pt( std::vector<double>{1,2,3}.data() );
2

Ваш код не работает: массив, возвращенный из лямбда-функции, уничтожается после возвращения из лямбда, но прежде чем передать его конструктору, где вы хотите его увидеть. Вероятно, код работает, но это самый худший случай неопределенного поведения.

Лично я думаю, вы должны рассмотреть лучший интерфейс. Если вы не можете изменить свой интерфейс, вы можете использовать что-то вроде этого:

typedef double array[3];
Point pt(&(array{ 1.2, 2.3, 3.4 })[0]);

Ещё вопросы

Сообщество Overcoder
Наверх
Меню