С++11: цикл for с двумя инкрементами
От: emergen  
Дата: 12.02.15 07:56
Оценка:
Добрый день! Подскажите пожалуйста можно ли средствами с++ сделать конструкцию подобную языку Python?



for col, row [(0, 23), (1, 12), (2, 41), (3, 10)]:

obj.setMatrix( col, row )


Т.е. необходимо запустить автоматический цикл сразу по двум явно указанным значениям.
Re: С++11: цикл for с двумя инкрементами
От: jazzer Россия Skype: enerjazzer
Дата: 12.02.15 07:59
Оценка: 2 (1) +1
Здравствуйте, emergen, Вы писали:

E>Добрый день! Подскажите пожалуйста можно ли средствами с++ сделать конструкцию подобную языку Python?


ну это просто массив из std::tuple<int,int> будет, а так все то же самое.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: С++11: цикл for с двумя инкрементами
От: emergen  
Дата: 12.02.15 08:05
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, emergen, Вы писали:


E>>Добрый день! Подскажите пожалуйста можно ли средствами с++ сделать конструкцию подобную языку Python?


J>ну это просто массив из std::tuple<int,int> будет, а так все то же самое.



А если вместо второго аргумента поставить указатели на объект типа

obj1 = MyObject();
obj2 = MyObject();
obj3 = MyObject();

td::tuple<int,MyObject()> ?

как в таком случае будет выглядеть цикл?
Re[2]: С++11: цикл for с двумя инкрементами
От: kvser  
Дата: 12.02.15 08:12
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, emergen, Вы писали:


E>>Добрый день! Подскажите пожалуйста можно ли средствами с++ сделать конструкцию подобную языку Python?


J>ну это просто массив из std::tuple<int,int> будет, а так все то же самое.


offtopic: А вообще из рсдн неплохой транлятор из питона в с++ может получится (и не только)
Re[3]: С++11: цикл for с двумя инкрементами
От: emergen  
Дата: 12.02.15 08:15
Оценка:
Здравствуйте, kvser, Вы писали:

K>Здравствуйте, jazzer, Вы писали:


J>>Здравствуйте, emergen, Вы писали:


E>>>Добрый день! Подскажите пожалуйста можно ли средствами с++ сделать конструкцию подобную языку Python?


J>>ну это просто массив из std::tuple<int,int> будет, а так все то же самое.


K>offtopic: А вообще из рсдн неплохой транлятор из питона в с++ может получится (и не только)


заинтересовала конструкция цикла! просто и удобно, вот хочу понять может ли С++11 такое сделать...
Re[3]: С++11: цикл for с двумя инкрементами
От: Igore Россия  
Дата: 12.02.15 08:20
Оценка: 3 (1)
Здравствуйте, emergen, Вы писали:

E>А если вместо второго аргумента поставить указатели на объект типа

E>как в таком случае будет выглядеть цикл?

Точно так же:
struct Test
{
     int i;
};

std::vector< std::tuple< int, Test* > > vec1;

for( auto& it : vec1 )
{
    std::get< 1 >( it )->i = std::get< 0 >( it );
    //Или так
    int index;
    Test* pointer;
    std::tie( index, pointer) = it;
    pointer->i = index;
}

//Если использовать pair то можно так
std::vector< std::pair< int, Test* > > vec2;
for( auto& it : vec2 )
{
    it.second->i = it.first;
}
Отредактировано 12.02.2015 8:21 Igore . Предыдущая версия .
Re[4]: С++11: цикл for с двумя инкрементами
От: emergen  
Дата: 12.02.15 08:38
Оценка:
Здравствуйте, Igore, Вы писали:

I>Здравствуйте, emergen, Вы писали:


E>>А если вместо второго аргумента поставить указатели на объект типа

E>>как в таком случае будет выглядеть цикл?

I>Точно так же:

I>
I>struct Test
I>{
I>     int i;
I>};

I>std::vector< std::tuple< int, Test* > > vec1;

I>for( auto& it : vec1 )
I>{
I>    std::get< 1 >( it )->i = std::get< 0 >( it );
I>    //Или так
I>    int index;
I>    Test* pointer;
I>    std::tie( index, pointer) = it;
I>    pointer->i = index;
I>}

I>//Если использовать pair то можно так
I>std::vector< std::pair< int, Test* > > vec2;
I>for( auto& it : vec2 )
I>{
I>    it.second->i = it.first;
I>}
I>



я так понял что std::tuple плох тем что нельзя явно (статически) задать значения и размер массива
т.е. нельзя написать std::tuple<int, MyObject(), 3 > = { (1, .. ), (3, .. ), (3, .. )}
Re[4]: С++11: цикл for с двумя инкрементами
От: enji  
Дата: 12.02.15 09:02
Оценка: +3
Здравствуйте, Igore, Вы писали:

Меня всегда интересовало, зачем tuple в нешаблонном коде. Имхо, значительно яснее сделать доп стуктуру

I>Точно так же:

I>
I>struct Test
I>{
I>     int i;
I>};

struct SomeUsefullStruct
{
     int index;
     Test *pointer;
};

std::vector<SomeRealName> vec1;

I>for( auto& it : vec1 )
I>{
    it.pointer->f(it.index);
I>}

I>


Объем тот же (если сравнить с вариантом int index; Test* pointer; std::tie( index, pointer) = it
Работает автокомплит, не надо вспоминать, какой член где лежит.
Если вдруг имена поменяются — будет ошибка компиляции.
Легко найти все использования.

Единственный минус — надо явно объявить структуру и дать нормальные имена.
Re[5]: С++11: цикл for с двумя инкрементами
От: jazzer Россия Skype: enerjazzer
Дата: 12.02.15 09:07
Оценка: +1
Здравствуйте, emergen, Вы писали:

E>я так понял что std::tuple плох тем что нельзя явно (статически) задать значения и размер массива

E>т.е. нельзя написать std::tuple<int, MyObject(), 3 > = { (1, .. ), (3, .. ), (3, .. )}

Можно, но не так:
std::tuple<int, MyObject> array[] = { {1, MyObject()}, {2, MyObject()}, {3, MyObject()} };

инициализация делается фигурными скобками, короче.

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

В С++, в отличие от управляемых языков типа Питона (в которых, к тому же, в основном ссылки-указатели летают), стараются лишних объектов не плодить.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[5]: С++11: цикл for с двумя инкрементами
От: Igore Россия  
Дата: 12.02.15 09:11
Оценка:
Здравствуйте, emergen, Вы писали:

E>Здравствуйте, Igore, Вы писали:


E>я так понял что std::tuple плох тем что нельзя явно (статически) задать значения и размер массива

E>т.е. нельзя написать std::tuple<int, MyObject(), 3 > = { (1, .. ), (3, .. ), (3, .. )}
std::tuple это кортеж а не массив, тебе нужен std::vector< std::tuple<int, MyObject > > или std::array< std::tuple<int, MyObject >, 3 >
python [(0, 23), (1, 12), (2, 41), (3, 10)], в С++ переходит в масив кортежей, std::vector< std::tuple< int, int > >;
В С++ ты не можешь распаковать кортеж прямо в for или range based for, лишнии строчти по сравнению с python-ом будут в любом случае.

P.S.
Так делать нельзя, но мой мозг выдал распоковку прямов в for
for( std::size_t i = 0; ( i < vec1.size() ? std::tie( index, pointer ) = vec1[ i ], true : false ); ++i )
{
    pointer->i = index;
}
Re[5]: С++11: цикл for с двумя инкрементами
От: jazzer Россия Skype: enerjazzer
Дата: 12.02.15 09:48
Оценка:
Здравствуйте, enji, Вы писали:

E>Меня всегда интересовало, зачем tuple в нешаблонном коде. Имхо, значительно яснее сделать доп стуктуру

E>Единственный минус — надо явно объявить структуру и дать нормальные имена.

+1. Кстати, я в питоне тоже почти все время namedtuple использую.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[5]: С++11: цикл for с двумя инкрементами
От: Evgeny.Panasyuk Россия  
Дата: 12.02.15 10:02
Оценка:
Здравствуйте, enji, Вы писали:

E>Меня всегда интересовало, зачем tuple в нешаблонном коде. Имхо, значительно яснее сделать доп стуктуру


Согласен
Автор: Evgeny.Panasyuk
Дата: 17.02.13
, сам предпочитаю структуры.
Хотя у tuple (или boost::fusion в более общем смысле) в нешаблонном коде всё же есть преимущества, например "автоматическое" лексикографическое сравнение — и прочие гетерогенные радости. Появление compile-time reflection конечно изменит ситуацию.
Re[6]: С++11: цикл for с двумя инкрементами
От: enji  
Дата: 12.02.15 10:36
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Появление compile-time reflection конечно изменит ситуацию.


а есть уже какие-то подвижки в эту сторону? В идеале хотелось бы компайл-тайм макросов (с циклами, переменными и всем прочим), в которых можно добраться до синтаксического дерева
Re[7]: С++11: цикл for с двумя инкрементами
От: jazzer Россия Skype: enerjazzer
Дата: 12.02.15 10:50
Оценка:
Здравствуйте, enji, Вы писали:

E>Здравствуйте, Evgeny.Panasyuk, Вы писали:


EP>>Появление compile-time reflection конечно изменит ситуацию.


E>а есть уже какие-то подвижки в эту сторону? В идеале хотелось бы компайл-тайм макросов (с циклами, переменными и всем прочим), в которых можно добраться до синтаксического дерева


В комитете по стандартизации есть подгруппа SG7, в ней рассматриваются как раз все связанные с рефлексией предложения.
https://groups.google.com/a/isocpp.org/d/forum/reflection

Например, вот такое предложение есть:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4111.pdf

struct A
{
  int a;
};

typedef mirrored(A) meta_A;

typedef meta::members<meta_A>::type meta_A_members;

static_assert(meta::size<meta_A_members>() == 1, ""); // A::a

// ну и
typedef meta::at<meta_A_members, 0>::type meta_A_a;
//и дальше работать с meta_A_a
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[7]: С++11: цикл for с двумя инкрементами
От: Evgeny.Panasyuk Россия  
Дата: 12.02.15 11:18
Оценка:
Здравствуйте, enji, Вы писали:

EP>>Появление compile-time reflection конечно изменит ситуацию.

E>а есть уже какие-то подвижки в эту сторону? В идеале хотелось бы компайл-тайм макросов (с циклами, переменными и всем прочим),

Там разные предложения были, и reflection структур, и улучшенные макросы.
Я бы предпочёл сначала получить reflection структур (а-ля BOOST_FUSION_ADAPT_*), потом возможность создавать новые структуры через мета-программирование (например на входе struct In { int x; };, на выходе struct Out { int &x; };), а уж потом всё остальное.

E>в которых можно добраться до синтаксического дерева


Насчёт доступа к синтаксическому дереву сомневаюсь — это же его нужно всё стандартизировать. AFAIK, внутри MSC++ до недавнего времени вообще не было AST
А вот что-то типа квази-цитирования, как в Nemerle — думаю возможно.
Отредактировано 12.02.2015 11:18 Evgeny.Panasyuk . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.