382 / 280 / 31
Регистрация: 04.09.2009
Сообщений: 1,225
1

Lambda init capture by const reference

20.03.2016, 21:30. Показов 1576. Ответов 9
Метки нет (Все метки)

Всем привет.

Почему не получается добиться следующего поведения:

C++
1
2
3
4
5
6
7
8
9
auto main() -> int
{
    int ival = 0;
 
    [&ival = ival]() { // Need something like '[const& ival = ival]'
        ++ival; // Need fail
    }();
 
}
Как заставить лямбду захватывать по константной сслыке? Именно захватывать, внутри квадратных скобок, т.е. bind и тому подобное не подходит.

Благодарю всех неравнодушных!
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
20.03.2016, 21:30
Ответы с готовыми решениями:

Variadic template lambda capture
Доброго всем дня! Речь пойдёт об C++14, в котором стало возможным делать прямую передачу в...

Lambda Capture — extending object's lifetime
Всем привет! // --- Поясняющий псевдокод. void SomeClass::func(Movable m) { Attribute& attr...

Ошибки: capture of non-variable Game::templog, 'this' was not captured for this lambda function
Пытаюсь очистить вектор mainlog от записей, встречающихся в векторе templog. Решение подсмотрел...

No init for const!
Доброе утро, котаны!:) Вопрос - в джаве есть возможность сделать такую штуку final boolean...

9
2542 / 1201 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
20.03.2016, 22:00 2
Это проблема в том, что С++ как баран разрешает в константных методов присваивать значения ссылкам. Как бы битовое состояние объекта не меняется - а на деле. Думаю тут надо класс wrapper для ival с сеттером и геттером соответствующего const состояния

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <string>
#include <sstream>
#include <fstream>
#include <iostream>
using namespace std;
 
struct A
{
    int x = 0;
    int& a;
 
    A() : a(x)
    {
 
    }
    void foo() const
    {
        a = 17;
    }
};
int main()
{
    const A a;
    cout << a.x << endl;
    a.foo();
    cout << a.x << endl;
}
1
382 / 280 / 31
Регистрация: 04.09.2009
Сообщений: 1,225
20.03.2016, 22:05  [ТС] 3
rikimaru2013, std::cref?
0
Игогошка!
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
20.03.2016, 22:06 4
Цитата Сообщение от gromo Посмотреть сообщение
Как заставить лямбду захватывать по константной сслыке?
Теоретически:
C++
1
2
3
[&ival = std::as_const(ival)]() { // Need something like '[const& ival = ival]'
  ++ival; // Need fail
}();
Но практически с этим проблемы. В gcc будет работать сейчас только такой код:
C++
1
2
3
4
5
const int& ival2 = static_cast<const int&>(ival);
 
[&ival2]() { // Need something like '[const& ival = ival]'
  ++ival2; // Need fail
}();
А в clang будет невменяемое сообщение об ошибке:
error: cannot assign to a variable captured by copy in a non-mutable lambda
0
382 / 280 / 31
Регистрация: 04.09.2009
Сообщений: 1,225
20.03.2016, 22:13  [ТС] 5
Цитата Сообщение от ct0r Посмотреть сообщение
const int& ival2 = static_cast<const int&>(ival);
А зачем явно кастить ?

Добавлено через 3 минуты
Вобщем через reference_wrapper получается добиться нужного эффекта и писанины не очень много, но все равно как-то костыльно. Но плюсовики — народ привыкший к такому
Кстати, as_const — вообще что-то адовое, по-моему. Писать вызов функции (концептуально), чтобы привести к константному виду
0
Игогошка!
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
20.03.2016, 22:18 6
Цитата Сообщение от gromo Посмотреть сообщение
А зачем явно кастить ?
Можно не кастить.
1) Просто для иллюстрации, что именно это делает as_const.
2) Когда я узнаю, что в гцц все пофиксили, будет проще найти такие места и поменять.
0
382 / 280 / 31
Регистрация: 04.09.2009
Сообщений: 1,225
20.03.2016, 22:24  [ТС] 7
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
С++ как баран разрешает в константных методов присваивать значения ссылкам
Тут вам скорее всего std::experimental:: propagate_const поможет. Еще одна crutch-feature

Цитата Сообщение от ct0r Посмотреть сообщение
Но практически с этим проблемы. В gcc будет работать сейчас только такой код:
А из-за чего вообще реджектится такой код на данный момент? Почему запрещена cv-конверсия ссылок?
0
Игогошка!
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
20.03.2016, 22:29 8
Цитата Сообщение от gromo Посмотреть сообщение
Кстати, as_const — вообще что-то адовое, по-моему. Писать вызов функции (концептуально), чтобы привести к константному виду
Почему же? Писать меньше и не надо знать сам тип объекта. Да и сам каст выглядит уродливо.

Цитата Сообщение от gromo Посмотреть сообщение
А из-за чего вообще реджектится такой код на данный момент? Почему запрещена cv-конверсия ссылок?
Ты в смысле, почему гцц отвергает теоретически правильный код? Ну так просто баг в гцц.
1
382 / 280 / 31
Регистрация: 04.09.2009
Сообщений: 1,225
21.03.2016, 01:03  [ТС] 9
Цитата Сообщение от ct0r Посмотреть сообщение
Да и сам каст выглядит уродливо.
Ну уродливые касты для того и введены были в С++, чтобы их можно было легче заметить, в отличие от C-style приведений (да, они более restrictive, но сейчас не об этом), а std::as_const получается более короткая запись [static|const]_cast. Что же это за отказ от заповедей С++?
0
Игогошка!
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
21.03.2016, 02:39 10
Цитата Сообщение от gromo Посмотреть сообщение
Что же это за отказ от заповедей С++?
Где отказ? У as_const нет ни одного недостатка, присущего сишным кастам. as_const:
1) Легок для понимания.
2) Нормально отыскивается как глазами, так и грепом.
3) И самое главное, безопасен, поэтому не нуждается в искусственной уродливости.
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.03.2016, 02:39

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

Rvalue reference and lambda
void foo(A&amp;&amp; a) { auto l = () {}; //a? } Как передать в лямбду rvalue ref как просто...

Const, pointers, reference
const int&amp; const ref1; const int &amp;ref1; int const &amp;ref1; Во всех случаях это константная...

Non-const lvalue reference to type
Добрый день. Мне надо передать указатель на матрицу (Шахматная доска) Piece* board в функцию...

Ошибка undefined reference to `QueueTp<Worker>::isfull() const'
Здравствуйте. Вот выводятся такие ошибочки. Помогите, плз, разобраться. Приведу некоторые файлы:...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.