2012-04-06 2 views
2

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

c++ passing a const object reference to a function

Passing const& as a function argument

оба не помогите мне, поэтому я указываю свою проблему здесь:

1) У меня есть класс Polygon, который хранит Point2D s в списке. Класс имеет среди других функций двух членов:

public:  
    std::pair<Point2D,Point2D> closestPts() const; 
private: 
    Tripel const& findClosestPts (std::vector<Point2D> const& P, 
           std::vector<Point2D> const& X, 
           std::vector<Point2D> const& Y) const; 

2) класс также содержит struct Triple, которое возвращаемое значение функции findClosestPts. Мне нужно это, потому что функция должна возвращать две точки и одно расстояние:

struct Tripel { 
    Point2D pt1; 
    Point2D pt2; 
    float dist; 
}; 

Проблема в настоящее время в реализации Polygon.cpp. Это мой (текущий) код для двух указанных выше функций:

std::pair<Point2D,Point2D> Polygon::closestPts() const { 
    ... 
    int size = m_points.size(); 
    std::vector<Point2D> P (size); 
    std::vector<Point2D> X (size); 
    std::vector<Point2D> Y (size); 
    ... 
    // some manipulation of the vectors, filling them with Point2D 
    // at this point, I have three non-const std::vector<Point2D> 

    // try to call the other function  
    Tripel closPts = findClosestPts(P, X, Y); 
    ... 
} 

Tripel const& findClosestPts (std::vector<Point2D> const& P, std::vector<Point2D> const& X, std::vector<Point2D> const& Y) const { 
    ... 
} 

Ошибка компилятора:

error: non-member function 'const Tripel& findClosestPts(...)' cannot have cv-qualifier 

Так что я предполагаю, что я не позволил сделать эту функцию const, потому что она возвращает struct. Это правда?

В любом случае, я изменил функцию подписи к этому:

Tripel const& findClosestPts (std::vector<Point2D> const& P, 
           std::vector<Point2D> const& X, 
           std::vector<Point2D> const& Y); 

Таким образом, функция не const больше. Это приводит к следующей компиляционной ошибке:

error: passing 'const Polygon' as 'this' argument of 'const Tripel& Polygon::findClosestPts(...)' discards qualifiers [-fpermissive] 

Я не знаю, что теперь делать. Я пробовал почти все, удаляя все утверждения const, меняя их, делая публичный findClosestPts, делая его снова const, создавая три std :: вектора const, прежде чем передавать их в другую функцию ... но все привело к (разным) компиляция ошибок.

Так что мой вопрос в том, как мне нужно написать две функции, чтобы добиться следующего: я хочу иметь функцию closestPoints(), которая является открытой функцией-членом и которая возвращает пару из двух ближайших точек. Для этого ему нужна вспомогательная, частная функция-член findClosestPts(vector1, vector2, vector3), которая возвращает вышеупомянутое struct Triple?

Я был бы рад помочь, потому что я здесь stucked поскольку время:/

+0

Вы действительно хотите вернуть ссылку на const? Это может легко привести к обманутой ссылке. «Triple», похоже, является типом значений в любом случае. – Andre

+0

Confusion: Is 'Triple' ===' Tripel'? –

+0

@ Robᵩ Я уверен, что они имеют в виду то же самое: английский и немецкий. ;-) – Andre

ответ

9

Вы можете сделать это const, вы просто забыли квалифицировать имя в реализации.

  //class name 
       || 
       \/ 
Tripel const& Polygon::findClosestPts (std::vector<Point2D> const& P, 
      std::vector<Point2D> const& X, std::vector<Point2D> const& Y) const 
+0

+1 длявыявление этих отвратительных синтаксических ошибок –

+0

Кровавый ад, который быстро набрал текст, я думал, что я довольно быстро – EdChum

2

Вы должны квалифицировать имя функции с именем класса, как

Tripel const& Polygon::findClosestPts (std::vector<Point2D> const& P, std::vector<Point2D> const& X, std::vector<Point2D> const& Y) const 

Luchian бил меня к нему, но ошибка говорит вам, что Non-член не может иметь резюме спецификатор, для того же причина того, что статические функции не могут быть квалифицированы Cv

3

ключ находится в сообщении об ошибке:

error: non-member function ... 

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

Tripel const& Polygon::findClosestPts(... 
+0

yep ... вот и все :) – MenschMarcus

0

Пожалуйста, обратите внимание, что лучше вернуться сюда:

Tripel const& findClosestPts (std::vector<Point2D> const& P, 
           std::vector<Point2D> const& X, 
           std::vector<Point2D> const& Y) const; 

значение Tripel, а не ссылку на него. Как уже отмечалось, это небезопасно, чтобы вернуть ссылку.

Такие функции почти всегда должны возвращать значение, а не ссылку, , так как в противном случае вам нужно будет сохранить время жизни объекта, возвращающего ссылку, с временем жизни объекта/кода, принимающего ссылку в переписке. То есть, время жизни возвращаемого объекта должно храниться в течение всего срока службы объекта или кода.

+0

спасибо, это было полезно! – MenschMarcus

+0

, но еще один вопрос: должен ли я вернуть его 'const' или просто так? – MenschMarcus

+0

Если вы возвращаете объект по значению, это всегда временный объект, и не имеет значения, является ли он CONST или нет (или какой-либо другой модификатор, такой как volatile и т. Д.), Поскольку объект не может быть фактически повторно использован, он полностью принадлежит принимающему кода, поэтому здесь ничего не нужно ограничивать. ~ 90% кода в C++ возвращает объекты по значению без модификаторов. – masterziv

0

Хорошо ... это было бы не стоило все это работа ... Я просто забыл класс спецификатор Polygon:: Это действительно неудобно, я извиняюсь :(

Спасибо всем за вашу помощь, я думаю, проблема решена!

Смежные вопросы