LINUX.ORG.RU

C++ передать аргумент в callback или организовать замыкание


0

2

Ситуация следующая:
Есть функция qStableSort(iterator, iterator, callback). Она из Qt, если это важно. Третьим параметром идёт имя функции-компаратора. Передать в эту функцию какой-то дополнительный аргумент возможности не предусмотрено. А отсортировать нужно двумерный массив, сначала по первой колонке, потом по второй и т.д. Таким образом для каждой колонки придётся делать свой callback, а меняется всего лишь номер колонки. Либо заводить глобальную переменную, что тоже плохо.
Есть ли какая другая возможность передать переменную в callback, может можно организовать нечто на подобии замыкания?

★★★

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

С++11х в зубы! А ежели компилятор старый, то зафигачь функциональный обьект вместо указателя на функцию!

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

Дайте пример пожалуйста, я начинающий :)

Olegymous ★★★
() автор топика

> qStableSort

И нафиг она тебе нужна? Просто используй sort или stable_sort из STL.

archimag ★★★
()

Просто погугли о функциональных обьектах на С++. Это обьект, в который можно передавать любые параметры, но еще в нем определен оператор (), потому его можно передвать вместо коллбека

vertexua ★★★★★
()

Только один из вариантов:

bool customSort(const QString &s1, const QString &s2,  SortKind kind)
{
    ... //magic here
}

int doSomething()
{
    QStringList list;
    ...
    SortKind kind = SortKind_first;
    qStableSort(list.begin(), list.end(), [&](const QString &s1, const QString &s2) { return customSort(s1, s2, kind); });
    kind = SortKind_second;
    qStableSort(list.begin(), list.end(), [&](const QString &s1, const QString &s2) { return customSort(s1, s2, kind); });
    ...
}
Pavval ★★★★★
()

> параметром идёт имя функции-компаратора. Передать в эту функцию какой-то дополнительный аргумент возможности не предусмотрено

Прочитай сначала про функторы, потом про boost::bind (и boost::function туда же).

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

Это как раз что-то из нового стандарта. На g++ 4.4 не завелось, а на 4.6 ок.
На будущее возьму на заметку, а пока функтор попробую осилить.

Olegymous ★★★
() автор топика

для сортировки по двум колонкам не нужно писать два разных callback-а

s0L
()
Ответ на: комментарий от Olegymous

Это как раз что-то из нового стандарта. На g++ 4.4 не завелось, а на 4.6 ок.

C++11, да. Меня уже палкой на старый стандарт не загонишь.

Pavval ★★★★★
()

Всем спасибо, я познал функторы ;)

#include <QtCore>

class sortFun
{     
	public:
		bool asc;
		
		bool operator()(QString a, QString b) const {
			if (!asc)
				return QString::compare(a, b) > 0 ? true : false;
			
			return QString::compare(a, b) > 0 ? false : true;
		}
};

int main() {
	QStringList qsl;
	qsl.append("mama");
	qsl.append("mila");
	qsl.append("aamu");
	
	qDebug() << qsl;
	
	sortFun fun;
	fun.asc = true;
	qStableSort(qsl.begin(), qsl.end(), fun);
	qDebug() << qsl;
	
	fun.asc = false;
	qStableSort(qsl.begin(), qsl.end(), fun);
	qDebug() << qsl;
	
	return 0;
}

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

>Меня уже палкой на старый стандарт не загонишь.

это если есть возможность его использовать :(

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

Жалко, в андроиде все еще stl не полностью поддерживается и никаких c++0x не намечается

note173 ★★★★★
()
Ответ на: к слову... от seed_stil

не нагуглил когда в гцц (хотя бы) ждать enum'ы

Строго типизированные перечисления? Так они уже есть.

C++0x Support in GCC

Begemoth ★★★★★
()

Это шаблон. 3м параметром можно функтор передать.

Reset ★★★★★
()
Ответ на: комментарий от Olegymous
		bool operator()(QString a, QString b) const {
			if (!asc)
				return QString::compare(a, b) > 0 ? true : false;
			
			return QString::compare(a, b) > 0 ? false : true;
		}
		bool operator()(QString a, QString b) const {
			return (QString::compare(a, b) > 0) ^ asc;
		}
unC0Rr ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.