LINUX.ORG.RU

Как объявить структуру? Что делать с namespace-ами?

 


0

3

Есть открыто-свободная игра на C++. Есть года 2 как неактивный патчсет. Я пытаюсь его перенести на последнюю версию движка, но почему-то не получается объявить переменную.

В патченном есть строка, которая теперь не компилируется:

getTileEngine()->calculateUnitLighting();
Потому что в новой версии calculateUnitLighting требует параметр типа GraphSubset:
void TileEngine::calculateUnitLighting(GraphSubset gs)

GraphSubset объявляется как структура из 4 целых, но с кучей функций GraphSubset() внутри:

namespace OpenXcom
{
struct GraphSubset
{
	int beg_x, end_x;
	int beg_y, end_y;

	GraphSubset(int max_x, int max_y):
			beg_x(0), end_x(max_x),
			beg_y(0), end_y(max_y)
	{
	}

	GraphSubset(std::pair<int, int> range_x, std::pair<int, int> range_y):
			beg_x(range_x.first), end_x(range_x.second),
			beg_y(range_y.first), end_y(range_y.second)
	{
	}

	GraphSubset(const GraphSubset& r):
			beg_x(r.beg_x), end_x(r.end_x),
			beg_y(r.beg_y), end_y(r.end_y)
	{
	}

	inline GraphSubset offset(int x, int y) const
	{
		GraphSubset ret = *this;
		ret.beg_x += x;
		ret.end_x += x;
		ret.beg_y += y;
		ret.end_y += y;
		return ret;
	}

	inline int size_x() const
	{
		return end_x - beg_x;
	}

	inline int size_y() const
	{
		return end_y - beg_y;
	}
/* половина функций вырезана */
};

}//namespace OpenXcom

При попытках объявить переменную типа GraphSubset получаю ошибку о неверном числе параметров — похоже это воспринимается как вызов одной из функций GraphSubset().

Объявление calculateUnitLighting: TileEngine.h, TileEngine.cpp. Объявление GraphSubset: GraphSubset.h.

В том же TileEngine.cpp есть функция

GraphSubset mapArea(Position position, int radius)
которая должна создавать GraphSubset из координат центра и радиуса, но при её вызове получаю ошибки наподобие «'mapArea' was not declared in this scope», " 'mapArea' is not a member of 'OpenXcom'" или «'class OpenXcom::TileEngine' has no member named 'mapArea'»
namespace OpenXcom
{
namespace
{

/* много пропущено */

GraphSubset mapArea(Position position, int radius)
{
	return { std::make_pair(position.x - radius, position.x + radius + 1), std::make_pair(position.y - radius, position.y + radius + 1) };
}

} // namespace

Вопрос: как вызвать эту функцию calculateUnitLighting() с параметром GraphSubset?

Ответ: mapArea — в анонимном пространстве имён, поэтому проще всего её повторить при создании экземпляра GraphSubset.

GraphSubset t1 = 
  GraphSubset( 
    std::make_pair( target.x - horiz_dist, target.x + horiz_dist + 1 ), 
    std::make_pair( target.y - horiz_dist, target.y + horiz_dist + 1 ) );
Но это оказалось бесполезно, так как calculateUnitLighting стала тоже приватной.

★★★★★

Последнее исправление: question4 (всего исправлений: 1)

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

При попытках объявить переменную типа GraphSubset получаю ошибку о неверном числе параметров — похоже это воспринимается как вызов одной из функций GraphSubset().

Думаю, правильно воспринимается, а сигнатура конструктора GraphSubset просто изменилась со временем.

tailgunner ★★★★★
()

namespace
{

Это анонимное пространство имён, оно недоступно из других файлов. Проще всего скопировать эту функцию туда, где она будет использоваться.

Но не факт, что эта функция делает то, что нужно в данном случае.

xaizek ★★★★★
()
Последнее исправление: xaizek (всего исправлений: 2)

но с кучей функций GraphSubset() внутри

Это называется конструкторы. Почему ты не прочитал наибазовую базу по плюсам прежде чем лезть в код и, тем более, писать сюда?

как вызвать эту функцию calculateUnitLighting() с параметром GraphSubset?

Создать GraphSubset указав координаты области в которой нужно посчитать освещение, очевидно.

slovazap ★★★★★
()
Ответ на: комментарий от tailgunner

полезно было бы привести сообщения компилятора об ошибках.

Я перепробовал много вариантов. Все не упомню. И ошибки длинные. Вот пример:

OpenXcom::GraphSubset::GraphSubset t1;
GraphSubset::GraphSubset t2;
GraphSubset t3;
OpenXcom::GraphSubset t4;

error: 'OpenXcom::GraphSubset::GraphSubset' names the constructor, not the type
       OpenXcom::GraphSubset::GraphSubset t1;
       ^
error: expected ';' before 't1'
       OpenXcom::GraphSubset::GraphSubset t1;
                                          ^
error: statement cannot resolve address of overloaded function
       OpenXcom::GraphSubset::GraphSubset t1;
                                            ^
error: 'OpenXcom::GraphSubset::GraphSubset' names the constructor, not the type
       GraphSubset::GraphSubset t2;
       ^
error: expected ';' before 't2'
       GraphSubset::GraphSubset t2;
                                ^
error: statement cannot resolve address of overloaded function
       GraphSubset::GraphSubset t2;
                                  ^
error: no matching function for call to 'OpenXcom::GraphSubset::GraphSubset()'
       GraphSubset t3;
                   ^
In file included from ... SavedBattleGame.cpp:45:0:
 ... GraphSubset.h:54:2: note: candidate: OpenXcom::GraphSubset::GraphSubset(const OpenXcom::GraphSubset&)
  GraphSubset(const GraphSubset& r):
  ^
 ... GraphSubset.h:54:2: note:   candidate expects 1 argument, 0 provided
 ... GraphSubset.h:47:2: note: candidate: OpenXcom::GraphSubset::GraphSubset(std::pair<int, int>, std::pair<int, int>)
  GraphSubset(std::pair<int, int> range_x, std::pair<int, int> range_y):
  ^
 ... GraphSubset.h:47:2: note:   candidate expects 2 arguments, 0 provided
 ... GraphSubset.h:39:2: note: candidate: OpenXcom::GraphSubset::GraphSubset(int, int)
  GraphSubset(int max_x, int max_y):
  ^
 ... GraphSubset.h:39:2: note:   candidate expects 2 arguments, 0 provided
 ... SavedBattleGame.cpp:1113:29: error: no matching function for call to 'OpenXcom::GraphSubset::GraphSubset()'
       OpenXcom::GraphSubset t4;
                             ^
In file included from  ... SavedBattleGame.cpp:45:0:
 ... GraphSubset.h:54:2: note: candidate: OpenXcom::GraphSubset::GraphSubset(const OpenXcom::GraphSubset&)
  GraphSubset(const GraphSubset& r):
  ^
 ... GraphSubset.h:54:2: note:   candidate expects 1 argument, 0 provided
 ... GraphSubset.h:47:2: note: candidate: OpenXcom::GraphSubset::GraphSubset(std::pair<int, int>, std::pair<int, int>)
  GraphSubset(std::pair<int, int> range_x, std::pair<int, int> range_y):
  ^
 ... GraphSubset.h:47:2: note:   candidate expects 2 arguments, 0 provided
 ... GraphSubset.h:39:2: note: candidate: OpenXcom::GraphSubset::GraphSubset(int, int)
  GraphSubset(int max_x, int max_y):
  ^

Думаю, правильно воспринимается, а сигнатура конструктора GraphSubset просто изменилась со временем.

Какой конструктор, если GraphSubset объявлен как struct, ни от чего явно не наследуется и слова «constructor» не содержит?

Кроме того, в других местах переменные этого типа объявляются просто как «GraphSubset variable_name;»:
https://github.com/MeridianOXC/OpenXcom/blob/oxce3.5-plus-proto/src/Engine/Sc...
https://github.com/MeridianOXC/OpenXcom/blob/oxce3.5-plus-proto/src/Engine/Sh...
https://github.com/MeridianOXC/OpenXcom/blob/oxce3.5-plus-proto/src/Engine/Sh...

Какая разница? На что обратить внимание?

question4 ★★★★★
() автор топика
Ответ на: комментарий от xaizek

Это анонимное пространство имён, оно недоступно из других файлов.

Спасибо, именно это я не понимал.

question4 ★★★★★
() автор топика
Ответ на: комментарий от slovazap

Почему ты не прочитал наибазовую базу по плюсам прежде чем лезть в код и, тем более, писать сюда?

Потому что читал неоднократно. Но C++ перемешалось с Delphi.

Создать GraphSubset указав координаты области в которой нужно посчитать освещение, очевидно.

Каким образом в других местах она объявляется без присвоения и явного вызова конструкторов?

question4 ★★★★★
() автор топика
Ответ на: комментарий от question4

Какой конструктор, если GraphSubset объявлен как struct

struct - это частный случай класса.

и слова «constructor» не содержит

Насколько я понимаю, это Си++? Там не нужно слово «constructor». Если имя функции совпадает с именем класса - это конструктор.

GraphSubset g = srcShader.getDomain()

Это вызов конструктора с одним аргументом. Конструктора копирования, вероятно (без знания типов сказать не могу).

const GraphSubset _range_base;

А это объявление объекта, который инициализируется здесь: https://github.com/MeridianOXC/OpenXcom/blob/oxce3.5-plus-proto/src/Engine/Sh...

Без обид, но тебе правда нужна книга по основам плюсов. При том, что код, насколько я могу судить, на современном диалекте плюсов.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от tailgunner

Насколько я понимаю, это Си++? Там не нужно слово «constructor».

Ага, уже вспомнил. Лет 5 к ним не прикасался.

тебе правда нужна книга по основам плюсов. При том, что код, насколько я могу судить, на современном диалекте плюсов.

Посоветуй, что прочесть. Есть что-нибудь короткое, как книга K&R? (Да, я знаю, что она по другому языку.)

Это вызов конструктора с одним аргументом.
А это объявление объекта, который инициализируется здесь:

Ага, и в других случаях получается то же. Тогда задача решена.

question4 ★★★★★
() автор топика
Последнее исправление: question4 (всего исправлений: 1)
Ответ на: комментарий от question4

Посоветуй, что прочесть. Есть что-нибудь короткое, как книга K&R?

Я последние 20 лет не слежу за учебниками по Си++ :) Могу только сказать, что коротких учебников по Си++ быть просто не может. В остальном - наверное, последнее издание Страуструпа - неплохой учебник.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

коротких учебников по Си++ быть просто не может

«Как K&R» — я имел в виду 300-400 страниц.

Изучаю список в прикреплённой теме.

question4 ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.