cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
89 stars 0 forks source link

Исправить внутренний тип переменной при захвате константной ссылки по значению в лямбдах #219

Open apolukhin opened 3 years ago

apolukhin commented 3 years ago

Перенос предложения: голоса +2, -5 Автор идеи: Антон

Сейчас при захвате константной ссылки (например const int &) по значению в лямбде получаем const (const int) переменную даже в случае mutable лямбды.

Имеем

int i = 0; const int &j = i;

Следующий код не компилируется в силу того, что лямбда не mutable (j внутри лямбды имеет тип const int) и это выглядит естественно.

[j]()
{
    j = 1;
}();

Следующий код тоже не компилируется, хотя мы явно указываем спецификатор mutable, (j внутри лямбды по-прежнему имеет тип const int).

[j]() mutable
{
    j = 1;
}();

Компилируется только код с явным указанием копии:

[j = j]() mutable
{
    j = 1;
}();

Было бы логичнее если mutable отменял const спецификаторы для всех внутренних переменных лямбды в любом случае.

apolukhin commented 3 years ago

Andrey Davydov, 18 августа 2017, 20:16 Это же будет breaking change? Рассмотрим, скажем, такой код (по сравнению с std::map в класс MyMap добавлен константный operator[]).

template<typename K, typename V>
struct MyMap
{
    /// @throw std::out_of_range if map doesn't contain \p k
    V const & operator[] (K const & k) const;

    /// @return reference to default constructed element if map doesn't contain \p k
    V operator[] (K const & k);
};

void foo(MyMap<int, int> const & map)
{
    auto lambda = [map] () {
        std::cout << map[239];
    };
}

Если принять Ваше предложение семантика lambda поменяется.

Антон, 18 августа 2017, 20:37 Andrey Davydov, по моему предложению код

auto lambda = [map] () {
    std::cout << map[239];
};

и не должен работать, должен

auto lambda = [map] () mutable {
    std::cout << map[239];
};

Andrey Davydov, 18 августа 2017, 20:49 anton_lashkov, но если mutable уже был (для модификации какой-то другой переменной), то map[239] ведь начнет работать по другому?

Антон, 18 августа 2017, 21:09 Andrey Davydov, да, еще раз взглянув на пример, я понял о чем вы, обратной совместимости не будет.

Andrey Davydov, 18 августа 2017, 21:15 anton_lashkov, значит, ни за что не примут, но если б изначально работало как Вы предлагаете, было бы клево.