LINUX.ORG.RU

[C++] конструкция, синтаксически выглядящая как вызов функции, но имеющая произвольное кол-во аргументов.

 


0

2

Есть нек-й класс, параметризованный по int

template <int D> class indx{
int p[D];
public:
indx( const int* Ap ){ for(int i=0;i<D;i++) p[i] = Ap[i]; }
...
};

Хочется иметь возможность создавать объекты при помощи конструкции вида Indx(1,3,15) // создает indx<3> с соотв. значениями.


stdarg.h использовать нельзя, т.к.
1) число аргументов неизвестно
2) производительность КРАЙНЕ важна.

Перегружать 50 вариантов порождающей ф-ии некрасиво.

Кто то что то может предложить? Пару решений я знаю, но пока не скажу, что б не ограничивать свободу воображения - м.б. кто то что то еще дельное предложит... ;-)))

★★★★★

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

> Кто то что то может предложить? Пару решений я знаю, но пока не скажу, что б не ограничивать свободу воображения

Если знаешь - то зачем завёл тему? Показать, какой ты умный и сообразительный? Много свободного времени и нечем занять - учавствуй в разработке любимых приложений на любимом языке.

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

Если нечего сказать по делу - зачем пишешь? Показать какой ты обсчетсвенный активист? Много свободного времени - сам написал что надо делать...

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

boost PREPROCESSOR

Перегрузи с помощью него

Количество параметров в момент вызова известно?

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

Количество параметров на момент компиляции известно ес-но, но может быть любым. Да, я выкрутился через обычный препроцессор (дефайн с произвольным кол-м аргументов), но вот беда - подсчет параметров через sizeof не работает внутри других шаблонов, т.е. конструкция

#define Indx(args...) ( indx< sizeof((int[]){args})/sizeof(int) >( (int[]){args} ) )

в каком нить template<class T> ... уже не собирается. Пришлось вводить

#define DIndx(D,args...) ( indx< D >( (int[]){args} ) )

это работает везде, неск. убого сморится. Мне интересно, еще как нить это можно сделать? Я пробовал через перегрузку оператора запятая - нестабильно выходит (аргументы то не приводятся), да и производительность... вызывает большие сомнения что компиялтор это все прально раскручивает.

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

через stdarg.h он написан, но это во первых медленно, во вторых надо знать кол-во аргументов.

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

В C++0x есть variadic templates, которые как раз позволяют писать типобезопаные функции с переменным числом параметров.

Begemoth ★★★★★
()

Пропустил, что в твоём примере значения одного типа, тогда ещё можно использовать initializer lists из C++0x.

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

Век живи, век учись, дураком помрешь...

За что ЛОР нравится - иногда всплывают такие пласты, о которых и понятия не имел. Спасибо, буду курить долгими зимними вечерами!;-)

А g++ это щастье C++0х поддерживает? И насколько хорошо, а то тут уже бились о то, что он рекрусивные шаблоны не особо хорошо с т.з. производительности раскручивает (ну по сравнению с обычными циклами), оптимизация явно хромает.

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

g++ поддерживает variadic templates с версии 4.3, что касается производительности - сказать не могу, не тестировал. Initializer list - с версии 4.4, тут с производительностью всё хорошо должно быть.

Begemoth ★★★★★
()

>Перегружать 50 вариантов порождающей ф-ии некрасиво.

А придется.

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

А...А...А... ладно, буду спрашивать по ходу. Еще раз спасибо!;-)))

Не все йогурты одинаково полезны! ;-))))))

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

Есть два варианта, в первом кол-во аргументов задается через отдельный аргумент (или явно указанный параметр шаблона), это просто реализуется но синтаксиески..эээ... грубовато. Во втором варианте кол-во аргументов не задается через отдельный аргумент и определяется автоматически.

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

#define DIndx(D,args...) ( indx< D >( (int[]){args} ) )

это работает везде, неск. убого сморится.

да нормально выглядит - ничего убогого (по крайней мере в показанном куске и на первый взгляд)

//сэр, я Вам на «келдыша» мыло отправил, Вы его видели или оно утонуло где?

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

пример использования: boost::bind

тащить буст из-за bind... что неужели настолько лучше встроенного?

shty ★★★★★
()

а по типу как в printf(...) разве не подойдет?

anonymous
()
Ответ на: комментарий от shty

Пришло, и я даже ответил! Еще аж 18/01/11 15:24... check trash?;-) Сейчас повторю.

да нормально выглядит

Мне местами не нравится. Лишние буковки, и в итоге код в одну строку не влезает;-))))

И потом, если число аргументов меньше заявленного, то все молча собирается но в недостающие аргументы встает что то из стека, и в итоге выходит плавающий сегфолт (поскольку по этому объекту многомерный массив индексируется).

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

1. Встроенного bind из tr1 или C++0x, ведь в C++03 только bind1st и bind2nd, чего мне лично не хватает.

2. Boost.Bind упоминался как пример реализации функции с переменным числом аргументов, и Boost предлагалось тащить ради Boost.Preprocessor.

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

Да-да, спасибо, Begemot меня туда уже послал;-)

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

> буду курить долгими зимними вечерами

Кошмар. На такую простую вещь столько времени убивать... С++ велик и могуч, епт.

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