Знаю что много подводных камней но все же...
Возможно ли на С++ сделать синтаксис типа такого:
method(param1, ..., paramN);
где method это функтор, param1 — paramN неограниченное количество параметров разного типа.
интересует правильная перегрузка operator= и operator, для данного случая.
Здравствуйте, AcidTheProgrammer, Вы писали:
ATP>Знаю что много подводных камней но все же... ATP>Возможно ли на С++ сделать синтаксис типа такого:
ATP>
ATP>method(param1, ..., paramN);
ATP>
ATP>где method это функтор, param1 — paramN неограниченное количество параметров разного типа. ATP>интересует правильная перегрузка operator= и operator, для данного случая.
Елси типы параметров разные, то следовательно вам пришлось бы перегружать этот оператор в каждом из них. Более того между всеми типами пришлось настраивать те или иные жесткие связи что усложнило бы масштабируемость. Попробуйте пересмотреть дизайн, или воспользуйтесь компилятором который поддерживает variadic templates
Здравствуйте, AcidTheProgrammer, Вы писали:
ATP>Знаю что много подводных камней но все же... ATP>Возможно ли на С++ сделать синтаксис типа такого:
ATP>
ATP>method(param1, ..., paramN);
ATP>
ATP>где method это функтор, param1 — paramN неограниченное количество параметров разного типа. ATP>интересует правильная перегрузка operator= и operator, для данного случая.
Нет, в таком виде не возможно. Но возможно в виде method((param1, ..., paramN));
Обратите внимание на двойные скобки.
Дело в том, что operator, перегрузить можно. Но при вызове функции работает не operator, а разделение параметров через запятую.
Здравствуйте, DKotin, Вы писали:
DK>Нет, в таком виде не возможно. Но возможно в виде method((param1, ..., paramN)); DK>Обратите внимание на двойные скобки. DK>Дело в том, что operator, перегрузить можно. Но при вызове функции работает не operator, а разделение параметров через запятую.
Да, я в принципе уже сам догадался до двойных скобок. Но проблемы все-равно остались: выражение в скобках у меня интерпретируется как один параметр, то есть срабатывает встроенный оператор ,, выходом которого является последнее выражение. Как с этим можно бароться?
ATP>Да, я в принципе уже сам догадался до двойных скобок. Но проблемы все-равно остались: выражение в скобках у меня интерпретируется как один параметр, то есть срабатывает встроенный оператор ,, выходом которого является последнее выражение. Как с этим можно бароться?
Очевидно, что типом, возвращаемым оператором , должен быть список параметров
Здравствуйте, AcidTheProgrammer, Вы писали:
ATP>Здравствуйте, DKotin, Вы писали:
DK>>Нет, в таком виде не возможно. Но возможно в виде method((param1, ..., paramN)); DK>>Обратите внимание на двойные скобки. DK>>Дело в том, что operator, перегрузить можно. Но при вызове функции работает не operator, а разделение параметров через запятую.
ATP>Да, я в принципе уже сам догадался до двойных скобок. Но проблемы все-равно остались: выражение в скобках у меня интерпретируется как один параметр, то есть срабатывает встроенный оператор ,, выходом которого является последнее выражение. Как с этим можно бароться?
Так тут и нужна перегрузка operator, для твоего класса.
Пусть у тебя method принимает параметр типа List
method(const List& list)
тогда в list нужены конструкторы, которые принимают типы параметров param1, param2
List::List(const Param1& param1)
List::List(const Param2& param2)
само собой, что в List должены хранится все param.
и в List нужно перегрузить operator, . При этом ндо перегрузить operator, для типа List и для всех типов Param.
const List operator,(const List& list);
const List operator,(const Param1& param1);
const List operator,(const param2& param2);
p.s. В С++ перегрузка operator, выглядит очень плохо. Попробуте пересмотреть дизайн или воспользоваться другим оператором (например operator+ тогда будет так method(param1 + param2 + .... + paramN)
Здравствуйте, DKotin, Вы писали:
DK>Так тут и нужна перегрузка operator, для твоего класса.
DK>Пусть у тебя method принимает параметр типа List DK>method(const List& list)
DK>тогда в list нужены конструкторы, которые принимают типы параметров param1, param2 DK>List::List(const Param1& param1) DK>List::List(const Param2& param2) DK>само собой, что в List должены хранится все param.
DK>и в List нужно перегрузить operator, . При этом ндо перегрузить operator, для типа List и для всех типов Param. DK>const List operator,(const List& list); DK>const List operator,(const Param1& param1); DK>const List operator,(const param2& param2);
DK>p.s. В С++ перегрузка operator, выглядит очень плохо. Попробуте пересмотреть дизайн или воспользоваться другим оператором (например operator+ тогда будет так method(param1 + param2 + .... + paramN)
В том то и дело, что с Param у меня все работает, не работает например такой код:
Здравствуйте, AcidTheProgrammer, Вы писали:
ATP>В том то и дело, что с Param у меня все работает, не работает например такой код: ATP>
ATP>method((1, 4))
ATP>
ATP> — передается один параметр 4, о чем я писал выше.
Забыл.
Нужен еще const List operator,(const Param1& lhs, const Param1& rhs); При этом подобные оперетры нужны для всех типов Param, плюс нужны операторы типа const List operator,(const Param1& lhs, const Param2& rhs); Лучше подобные вещи реализовывать через шаблоны.
И еще раз method должен принимать List, а не перам. Ввиду того, что у тебя код скомпилировался, то у тебя method принимает Param, а не List
Здравствуйте, DKotin, Вы писали:
DK>Забыл. DK>Нужен еще const List operator,(const Param1& lhs, const Param1& rhs); При этом подобные оперетры нужны для всех типов Param, плюс нужны операторы типа const List operator,(const Param1& lhs, const Param2& rhs); Лучше подобные вещи реализовывать через шаблоны.
DK>И еще раз method должен принимать List, а не перам. Ввиду того, что у тебя код скомпилировался, то у тебя method принимает Param, а не List
Есть у меня такой оператор — всеравно выражение method((1, 4)) воспринимается как method(Param(4)), а мне бы хотелось method((Param(1), Param(4))). Проблемма, если в скобках стоят только стандартные типы. А нельзя ли минимальный примерчик... Предположим что класс Param есть и он может хранить любой тип
Здравствуйте, AcidTheProgrammer, Вы писали:
ATP>Знаю что много подводных камней но все же...
Именно из-за подводных камней лучше перегружать не запятую, а что-нибудь более явное.
Скобки там, %, <<
Чтобы заработал именно перегруженный оператор, нужно
— двойные скобки — чтобы компилятор не принял монолитное выражение за список аргументов
— первый аргумент с перегруженной запятой
method((start, x, y, z));
Это ничем не красивее такого варианта
method(start << x << y << z);
method(start % x % y % z);
method(start(x)(y)(z));
А может, вот так сделать?
curried(method)(x)(y)(z);
Но на самом деле, можно поступить проще. Отказаться от амбиций в велосипедостроении и воспользоваться boost
boost::bind(method, x, y, z);
method(boost::tuple(x,y,z));
в зависимости от того, что именно тебе надо.
Там уже с помощью препроцессора нагенерили достаточно перегрузок по числу параметров.
Здравствуйте, Кодт, Вы писали:
К>Именно из-за подводных камней лучше перегружать не запятую, а что-нибудь более явное. К>Скобки там, %, <<
К>Чтобы заработал именно перегруженный оператор, нужно К>- двойные скобки — чтобы компилятор не принял монолитное выражение за список аргументов К>- первый аргумент с перегруженной запятой К>
К>method((start, x, y, z));
К>
К>Это ничем не красивее такого варианта К>
К>method(start << x << y << z);
К>method(start % x % y % z);
К>method(start(x)(y)(z));
К>
К>А может, вот так сделать? К>
К>curried(method)(x)(y)(z);
К>
К>Но на самом деле, можно поступить проще. Отказаться от амбиций в велосипедостроении и воспользоваться boost К>
К>boost::bind(method, x, y, z);
К>method(boost::tuple(x,y,z));
К>
К>в зависимости от того, что именно тебе надо.
К>Там уже с помощью препроцессора нагенерили достаточно перегрузок по числу параметров.