powered by simpleCommunicator - 2.0.58     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / fold expression и запятая (comma)
17 сообщений из 17, страница 1 из 1
fold expression и запятая (comma)
    #40003901
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет!

Споткнулся на ровном месте и что-то туплю с fold expression...
Начну издалека

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
struct summator
{
	template <typename ...T>
	summator(T&& ...Args) : value(((Args + 5) + ...))
	{}

	int value = 0;
};

int main(...)
{
	summator s(1, 1, 1);

	return s.value;
}



словами:
есть класс, в конструктор которого можно передавать произвольные объекты (в нашем примере это int, но в реальности все несколько сложнее). Конструктор складывает переданные значения и сохраняет в переменной-члене класса value.

Мне необходимо добавить к каждому переданному значению какое-то фиксированное число, в моем примере это 5.
На выходе я ожидаю получить:

1 + 5 + 1 + 5 + 1 + 5 = 18

Приведенный выше код прекрасно работает по описанному сценарию для int'ов.

Усложним задачу.

Предположим, что value - это не int, а другой класс (назовем его concatenator), который умеет конкатенировать из любых (в разумных чертах) типов данных в общую строку.
Я умышленно не привожу код concatenator'a ввиду его объема и сложности, в котором никто разбираться не будет. Но он у меня есть и он работает нормально.

Пример,
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
struct summator
{
	template <typename ...T>
	summator(T&& ...Args) : value(((Args, ';'), ...))
	{	}

	concatenator value;
};

summator s('a', 'b', 'c');
if (s.value == "a;b;c;")
// успешно
else
// ошибка


вместо 5, я подставляю к каждому аргументу точку с запятой, но у меня не получается достичь аналогичного результата как с int'ами.

Если я использую concatenator напрямую
Код: plaintext
1.
concatenator с('a', ';', 'b, ';'', 'c', ';');


то результат нормальный и ожидаемый, я получаю строку - "a;b;c;"
если же я использую вызов конструктора concatenator опосредовано, через summator (который должен сам добавить ';' , после каждого указанного аргумента), то на выходе я получаю строку состоящую только из точки с запятой .

получается что я неправильно пишу выражение fold expression в данном случае?
а как правильно написать его, чтобы получить тоже самое на входе конструктора, что и здесь
Код: plaintext
1.
concatenator с('a', ';', 'b, ';'', 'c', ';');

?

PS или это какой-то баг компилятора тынц , тынц
--------------------------------------------------------------
o(O_O)o
...
Рейтинг: 0 / 0
fold expression и запятая (comma)
    #40003919
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще непонятно какая проблема решается. Зачем ты решил добавить точки с запятой?
...
Рейтинг: 0 / 0
fold expression и запятая (comma)
    #40003930
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Вообще непонятно какая проблема решается. Зачем ты решил добавить точки с запятой?

для примера, к реальной задаче данный код имеет опосредованное отношение, но он ее описывает в удобном для анализа на форуме виде. Насколько это мне удалось, решать не мне, но я отвечу на любые вопросы, если что-то не понятно.

Проблема, которую я пытаюсь решить, заключается в том, что мне не удается передать в конструктор объекта массив аргументов разделенных нужной мне вставкой, при помощи fold expression

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
class A
{
    template <typenаme ...T>
    A(T&&... t)
    {
        // я хочу здесь после каждого t[0], t[1], .... t[n]
        // вставить в последовательность некие данные и передать их дальше на обработку в виде
        // t[0], x, t[1], x, .... t[n], x
    }
}


Чтобы такого еще придумать для наглядности...

Ну вот возьмем к примеру CSV таблицу, в которой каждое значение в столбце разделено ; (точкой с запятой)
Вам нужно передать только данные столбцов, а код сериализует их в CSV, подставив после каждого введенного значения символ-разделитель.

Код: plaintext
1.
2.
3.
4.
class CSV {...}

CSV csv("мама", "мыла", "раму");
auto x = csv.value(); // x должен быть строкой вида "мама;мыла;раму" 


так понятнее?
...
Рейтинг: 0 / 0
fold expression и запятая (comma)
    #40003943
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тебе принципиально, чтобы в шаблоне с VarArgs использовались разные типы параметров или у тебя все параметры одного и того же типа?
...
Рейтинг: 0 / 0
fold expression и запятая (comma)
    #40003948
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cerebrum
Чтобы такого еще придумать для наглядности...

Ну вот возьмем к примеру CSV таблицу, в которой каждое значение в столбце разделено ; (точкой с запятой)
Вам нужно передать только данные столбцов, а код сериализует их в CSV, подставив после каждого введенного значения символ-разделитель.
Загоняешь в ресурсы объекта значения полей (можно и через конструктор), а реализацию функции экспорта делаешь с параметром delimiter. Зачем разделитель в конструктор-то фигачить?
...
Рейтинг: 0 / 0
fold expression и запятая (comma)
    #40003949
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev
Тебе принципиально, чтобы в шаблоне с VarArgs использовались разные типы параметров или у тебя все параметры одного и того же типа?

в реальной задаче - да, но с этим нет проблем, т.к. с задачей конвертации прекрасно справляется мой класс concatenator'a, он преобразует переданные ему данные к "общему знаменателю", например

Код: plaintext
1.
2.
3.
class concatenator {...}

concatenator c(5, "-мама", L'=', 3.14f, "рама");


то на выходе я получу
"5-мама=3.14рама"

и это работает!

мне теперь хочется нахлабучить сверху механизм позволяющий вставлять произвольный разделитель между компонентами. И вроде как компилятор схавал мой код:
Код: plaintext
1.
2.
3.
template <typename ...T>
summator(T&& ...Args) : value(((Args, ';'), ...))
{	}


но вместо " 5;-мама;=;3.14;рама; ", я получаю только ";"

вызов конструктора при этом сопровождается только передачей символа разделителя, как-будто fold expression криво разворачивается и вместо (arg1, arg2, arg3...., argN), я получаю некий аналог (argN), а запятая в данном случае это не разделитель аргументов конструктора (функции), а оператор, который просто перебрал все аргументы и впихнул последний.
...
Рейтинг: 0 / 0
fold expression и запятая (comma)
    #40003958
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev
Зачем разделитель в конструктор-то фигачить?

пример с CSV искусственный и приведен в качестве образца.

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

поскольку используя variadic pack я могу получить сразу и всё: переданные значения и их типы, а также constexpr цикл с помощь fold expression, то я могу сразу произвести нужную мне обработку.
И как показывает практика с int'aми это работает (потому что там оператор +, а не запятая)

Если же использовать предложенный вами метод, то я должен буду сначала накопить эти данные в некий вектор, а при сериализации подставлять delimeter после каждой итерации, но мне нет смысла хранить эти данные. Я уже на этапе преобразования готов к их сериализации и именно она и происходит, так что плодить очередную копию данных особого смысла нет, нужно уже их записывать, либо передавать в какой-то транспорт в готовом виде

мне проще будет отказаться от этой идеи и сразу пихать нужный мне разделитель руками, без автоматизации в виде нахлабучки summator'a. И это прекрасно работает, проверено и не однократно.
...
Рейтинг: 0 / 0
fold expression и запятая (comma)
    #40003960
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
fold expression и запятая (comma)
    #40003970
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cerebrum, Args должен быть последним параметром, это основное требование.
...
Рейтинг: 0 / 0
fold expression и запятая (comma)
    #40003972
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev
Cerebrum, Args должен быть последним параметром, это основное требование.

что имеется ввиду?

Код: plaintext
1.
((';', Args),...)



?
...
Рейтинг: 0 / 0
fold expression и запятая (comma)
    #40003975
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cerebrum, да.
...
Рейтинг: 0 / 0
fold expression и запятая (comma)
    #40003976
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
если так делаю, то в конструктор прилетает только последний Args

ладно, забейте, руками прописывать разделитель буду

спасибо за участие
...
Рейтинг: 0 / 0
fold expression и запятая (comma)
    #40004030
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_dev
Cerebrum, Args должен быть последним параметром, это основное требование.
Чушь.

Cerebrum, ты в курсе про отличие оператора запятая от запятой в синтаксисе вызова функции?
А то, что ты хочешь, делается так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
#include <tuple>
using namespace std;

struct concatenator
{
  template<typename... Ts>
  concatenator(Ts... Args) {}
};

struct summator
{
  concatenator c;
  
  template<typename... Ts>
  summator(Ts... Args)
  : c(make_from_tuple<concatenator>(tuple_cat(make_tuple(Args, ';')...)))
  {}
};

summator s('a', 'b', 'c');
...
Рейтинг: 0 / 0
fold expression и запятая (comma)
    #40004039
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guest
Cerebrum, ты в курсе про отличие оператора запятая от запятой в синтаксисе вызова функции?

конечно, написал уже об этом несколькими постами выше
...
Рейтинг: 0 / 0
fold expression и запятая (comma)
    #40004040
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guest
rdb_dev
Cerebrum, Args должен быть последним параметром, это основное требование.
Чушь.
Так добавь в параметры summator какой-нибудь фиктивный аргумент после Args и проверь, а тот Args, что ты используешь в tuple, это уже развёртка.
...
Рейтинг: 0 / 0
fold expression и запятая (comma)
    #40004060
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_dev, тебя не поймёшь. Сначала ты пишешь про параметры, потом про аргументы.
...
Рейтинг: 0 / 0
fold expression и запятая (comma)
    #40005383
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guest, чего тут понимать? Просто путаю кто на ком лежал... Для меня без разницы кто сверху, а кто с низу, главное - процесс. :)
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / fold expression и запятая (comma)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]