Re[6]: range based for - первый/последний?
От: rg45 СССР  
Дата: 14.03.19 14:29
Оценка:
Здравствуйте, B0FEE664, Вы писали:

R>>Так вот это оно самое.

BFE>Да неужели?

Да точно-точно.

BFE>А писать ++it вместо it++ — тоже преждевременная оптимизация?


Нет. Но писать it++ вместо ++it — это преждевременная пессимизация. Зачем писать более сложное выражение, когда можно написать более простое при прочих равных условиях? Подробнее здесь: https://doc.lagout.org/programmation/C/CPP101.pdf, рекомендация №9: "Don't pessimize prematurely".
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 14.03.2019 14:31 rg45 . Предыдущая версия . Еще …
Отредактировано 14.03.2019 14:30 rg45 . Предыдущая версия .
Re[7]: range based for - первый/последний?
От: B0FEE664  
Дата: 14.03.19 14:42
Оценка:
Здравствуйте, andrey.desman, Вы писали:

AD>Ибо потому что через тупл надо, потому что тут присваивание, а значит {} описывает initializer_list вместо конструктора. Были бы разные типу у it и i2, то даже до этого не дошел бы.

А откуда тут initializer_list ? Зачем он тут?
struct A
{
    int n;
    char* s;
};
A a = {1, nullptr};



А если убрать присваивание, то почему не работает?
auto [a, b]{i1, i2};
И каждый день — без права на ошибку...
Re[8]: range based for - первый/последний?
От: andrey.desman  
Дата: 14.03.19 15:53
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Здравствуйте, andrey.desman, Вы писали:


AD>>Ибо потому что через тупл надо, потому что тут присваивание, а значит {} описывает initializer_list вместо конструктора. Были бы разные типу у it и i2, то даже до этого не дошел бы.

BFE>А откуда тут initializer_list ? Зачем он тут?

Потому что так придумали.
A std::initializer_list object is automatically constructed when: a braced-init-list is bound to auto, including in a ranged for loop

BFE>
BFE>struct A
BFE>{
BFE>    int n;
BFE>    char* s;
BFE>};
BFE>A a = {1, nullptr};
BFE>

BFE>

Это copy-list-initialization и там не initializer_list, а braced-init-list.

BFE>А если убрать присваивание, то почему не работает?

BFE>
BFE>auto [a, b]{i1, i2};
BFE>


С чего бы ей работать?
Смотри как объявляется structured binding https://en.cppreference.com/w/cpp/language/structured_binding.
В expression вообще запятой быть не положено, а когда ты = убираешь, то оно спотыкается уже на этом.

Твой изначальный код — это примерно следующее:
int i;
char c;

auto list = { i, c }; // initalizer_list, fail

auto [a, b] = list; // fail даже если list состояится как initializer_list, потому что он не массив и не тупл, значит привязка пойдет по членам класса.
Re[9]: range based for - первый/последний?
От: B0FEE664  
Дата: 14.03.19 16:44
Оценка:
Здравствуйте, andrey.desman, Вы писали:

BFE>>А откуда тут initializer_list ? Зачем он тут?

AD>Потому что так придумали.
Предположим, что так, хотя я сомневаюсь.

AD>A std::initializer_list object is automatically constructed when: a braced-init-list is bound to auto, including in a ranged for loop

А это наш случай? У нас structured binding, а не bound to auto. Разве это одно и тоже?

AD>Это copy-list-initialization и там не initializer_list, а braced-init-list.

Что говорит нам о том, что типы не обязаны быть одинаковыми. initializer_list не нужен.

BFE>>А если убрать присваивание, то почему не работает?

BFE>>
BFE>>auto [a, b]{i1, i2};
BFE>>

AD>С чего бы ей работать?
С того, что ничему не противоречит.
AD>Смотри как объявляется structured binding https://en.cppreference.com/w/cpp/language/structured_binding.
Я смотрел.

AD>В expression вообще запятой быть не положено, а когда ты = убираешь, то оно спотыкается уже на этом.

Не должно быть оператора запятая. Где у меня операторы?

AD>Твой изначальный код — это примерно следующее:

AD>auto list = { i, c }; // initalizer_list, fail
initalizer_list отсутствует в structured binding описании.

Предположим, что всё так, как вы пишите. Тогда получается, что это практически безполезная фича языка. Жаль, могла получиться красивая конструкция.
И каждый день — без права на ошибку...
Re[10]: range based for - первый/последний?
От: _NN_ www.nemerleweb.com
Дата: 14.03.19 17:03
Оценка:
Увы но это так
https://stackoverflow.com/questions/44666169/initializer-list-and-structured-bindings-deduction-ambiguity-in-c17

Насколько я понимаю в теории можно специализировать std::get для initalizer_list и тогда код соберётся
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[10]: range based for - первый/последний?
От: andrey.desman  
Дата: 14.03.19 17:41
Оценка:
Здравствуйте, B0FEE664, Вы писали:

AD>>A std::initializer_list object is automatically constructed when: a braced-init-list is bound to auto, including in a ranged for loop

BFE>А это наш случай? У нас structured binding, а не bound to auto. Разве это одно и тоже?
Наш. См. ниже.

AD>>Это copy-list-initialization и там не initializer_list, а braced-init-list.

BFE>Что говорит нам о том, что типы не обязаны быть одинаковыми. initializer_list не нужен.
Тут не обязаны, тут не нужен.

BFE>С того, что ничему не противоречит.

Противоречит описанию.

AD>>В expression вообще запятой быть не положено, а когда ты = убираешь, то оно спотыкается уже на этом.

BFE>Не должно быть оператора запятая. Где у меня операторы?
У выражения не может быть не оператора ",", поэтому там именно оператор.

AD>>Твой изначальный код — это примерно следующее:

AD>>auto list = { i, c }; // initalizer_list, fail
BFE>initalizer_list отсутствует в structured binding описании.

Ему там и не надо быть. Если expression не массив, то.

Otherwise e is defined as if by using its name instead of [ identifier-list ] in the declaration.


Т.е.
auto [a, b] = {1,2,3};
// =>
auto e = {1,2,3}; // initializer_list
...


BFE>Предположим, что всё так, как вы пишите. Тогда получается, что это практически безполезная фича языка. Жаль, могла получиться красивая конструкция.


Почему бесполезная? Потому что присваивания параллельными пачками нельзя делать, не написав std::tuple?
Re[11]: range based for - первый/последний?
От: B0FEE664  
Дата: 14.03.19 17:44
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Насколько я понимаю в теории можно специализировать std::get для initalizer_list и тогда код соберётся

Там сказано, что можно просто написать:

 const auto [x, y] = std::forward_as_tuple(a, b);

Жить можно, но мне не нравится. Нет краткости.
И каждый день — без права на ошибку...
Re[11]: range based for - первый/последний?
От: B0FEE664  
Дата: 14.03.19 17:52
Оценка:
Здравствуйте, andrey.desman, Вы писали:

AD>Почему бесполезная? Потому что присваивания параллельными пачками нельзя делать, не написав std::tuple?

Почему С++ не называется "с = с + 1"?
Вот и тут так же.
И каждый день — без права на ошибку...
Re[12]: range based for - первый/последний?
От: rg45 СССР  
Дата: 14.03.19 17:56
Оценка: :)
Здравствуйте, B0FEE664, Вы писали:

BFE>Почему С++ не называется "с = с + 1"?


Потому, что "с = с + 1" — это ++С

А С++ — это "(c = c + 1, c — 1)".
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 14.03.2019 18:02 rg45 . Предыдущая версия .
Re[12]: range based for - первый/последний?
От: _NN_ www.nemerleweb.com
Дата: 14.03.19 20:07
Оценка:
using fat = ::std::forward_as_tuple;

Или хочется новый синтаксис ввести в язык ?
Можно попытаться через stdcpp.ru
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[13]: range based for - первый/последний?
От: B0FEE664  
Дата: 14.03.19 21:57
Оценка: :)
Здравствуйте, rg45, Вы писали:

BFE>>Почему С++ не называется "с = с + 1"?

R>Потому, что "с = с + 1" — это ++С

Connoisseurs of C semantics find C++ inferior to ++C.


отсюда.
И каждый день — без права на ошибку...
Re[13]: range based for - первый/последний?
От: B0FEE664  
Дата: 14.03.19 22:26
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>
using fat = ::std::forward_as_tuple;

_NN>Или хочется новый синтаксис ввести в язык ?
Так в том-то и дело, что синтаксис новый добавили, но с несколько неожиданным поведением.

_NN>Можно попытаться через stdcpp.ru

Сначало можно тут обсудить.

Например, можно было бы ввести новый оператор, который никакой роли сам в языке по себе не играет, но который можно перегрузить для любого, не только пользовательского типа.

float operator =>(MyVariant from, float to)
{
  if ( ! from.IsFloat() )
    throw std::bad_cast();
        
  to = from.get<float>();

  return to;
}

int operator =>(float from, int to)
{
  if ( static_cast<float>(static_cast<int>(from)) != from )
    throw std::bad_cast();
        
  to = static_cast<int>(from);

  return to;
}


Использование:
MyVariant my(1.2f);
float my => f;
int f => n;

float x = 1.f;
o => x;
И каждый день — без права на ошибку...
Re: range based for - первый/последний?
От: Alexey F  
Дата: 15.03.19 18:05
Оценка:
Здравствуйте, Marty, Вы писали:

M>можно определить первый/последний элемент?

Для C++17 что-то вроде такого: http://reedbeta.com/blog/python-like-enumerate-in-cpp17/

Тогда:
std::size_t const size = std::size( data );
for( auto [ i, v ] = enumerate( data ) ) {
    if( i == 0 ) {} // первый элемент (или единственный, если size( data ) == 1)
    else if( i + 1 == size ) {} // последний элемент
    else {} // между первым и последним
}


Для вывода с запятыми:
for( auto [ i, v ] : enumerate( data ) ) {
    if( i != 0 ) {
        std::cout << ", ";
    }
    std::cout << v;
}
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.