
Roman
13.07.2018
16:56:23
Наткнулся на такую ошибку компиляции в моём коде : https://stackoverflow.com/questions/51329748/type-deduction-in-switch-and-sfinae-gcc-vs-clang
Какой компилятор прав по стандарту? Должен ли Sfinae в этом случае сработать?

Alexander
13.07.2018
16:58:58

Constantine
13.07.2018
16:59:08

Alexander
13.07.2018
17:05:07
for (auto [x,y] : map) vs for (auto& [x,y] : map)

Google

Alexander
13.07.2018
17:05:24
вроде за этим
http://coliru.stacked-crooked.com/a/a32fb9caeeef097b

Constantine
13.07.2018
17:18:09

Alexander
13.07.2018
17:18:52
x,y теже да
но если ты хочешь поменять Y y всех в мапе в цикле тебе нужен auto & [x,y]

Constantine
13.07.2018
17:20:22

Alexander
13.07.2018
17:21:05
ну прости это разные конструкции языка

Constantine
13.07.2018
17:21:22
разные что

Alexander
13.07.2018
17:21:40
auto x,y и auto [x,y]

Constantine
13.07.2018
17:21:44
угу
ну прости это разные конструкции языка
что по-вашему выведет программа?
#include <functional>
#include <utility>
template <typename... Args>
auto proxy(Args&&... args) {
return std::forward_as_tuple<Args...>(args...);
}
int f() {
int x = 0;
auto [y] = proxy(x);
auto z = std::get<0>(proxy(x));
y = 1;
z = 2;
return x;
}

Antony
13.07.2018
17:45:53

Google

Constantine
13.07.2018
17:46:33
Что на земле вообще мешало при бинде auto [x, y] = std::tie(a, b); делать x и y значениями?

Antony
13.07.2018
17:47:47
там используется tuple_element, а он в данном случае int&

Constantine
13.07.2018
17:48:11
да, но выражение auto z = std::get<0>(proxy(x));
а тут почему-то decltype(auto) y = std::get<0>(proxy(x));
при синтаксисе auto [y] = proxy(x)

Antony
13.07.2018
17:49:27
да

Constantine
13.07.2018
17:50:12
а я так надеялся, что придет 17 стандарт и я наконец-то удалю две реализации zip и zip_view и буду писать auto [a, b] и auto & [a, b]

Antony
13.07.2018
17:50:43
и это при том, что есть const auto& [y] = proxy(x);
давйте issue заведём на CWG
но я очень сомневаюсь, что ситуация изменится

Constantine
13.07.2018
17:51:36
так это ломает пользовательский код
так что можно только задаваться вопросом "НУ ПОЧЕМУ"

Andrey
13.07.2018
17:55:07

Constantine
13.07.2018
17:55:27
т.е. если я пишу auto name = /*expression*/ я точно уверен, что name это не ссылка

Andrey
13.07.2018
17:56:36
ЗАТЕМ что выбирать declaration specifiers для того что справа от = важнее чем для того что слева от =

Constantine
13.07.2018
17:56:52
нет!
выражение справа является типичным expression для которого есть стандартные правила auto&&
прямо как в range-based for
for (auto x : expression) вы настраиваете x, а не expression

Google

Constantine
13.07.2018
17:59:37
перенастройка expression делается одним оператором!
у меня в проекте он называется utils::copy_of
//
//copy_of
//
template <typename T>
std::decay_t<T> copy_of(T const& t)
{
return t;
}

Andrey
13.07.2018
18:01:19
это что-то что ведет себя похоже на ссылку
как, скажем, class member

Constantine
13.07.2018
18:02:08
а это не ссылка: https://godbolt.org/g/hHc49Y
#include <functional>
#include <utility>
template <typename... Args>
auto proxy(Args&&... args) {
return std::forward_as_tuple<Args...>(args...);
}
int f() {
int x = 0;
auto [y] = proxy(x);
auto z = std::get<0>(proxy(x));
y = 1;
z = 2;
return x;
}
конструкция auto [y] объявляет ссылку

Andrey
13.07.2018
18:02:49
нет

Constantine
13.07.2018
18:03:00
функция выводит 1

Andrey
13.07.2018
18:06:04
это я понимаю, но это не ссылка см. https://godbolt.org/g/hHc49Y

Antony
13.07.2018
18:10:25

Constantine
13.07.2018
18:15:20

Andrey
13.07.2018
18:16:14
Проблема в том, что такой код не компилируется
struct pair { const int x = 1; int y; };
pair p;
auto & x = p.x, & y = p.y;
auto & не может вывести одновременно Key const & и Value &

Constantine
13.07.2018
18:22:42
подразумевается return p.y но сути не меняет

Google

Andrey
13.07.2018
18:26:44
я имею в виду, что если в конструкции
for (auto & [k, v] : ...)
разрешить для одной компоненты вывести & а для другой const & будет как-то не очень

Constantine
13.07.2018
18:27:55
вот вам еще пример
https://godbolt.org/g/PjPJGT
часть распаковки не модифицировалась

Andrey
13.07.2018
18:31:57

Constantine
13.07.2018
18:32:40

Andrey
13.07.2018
18:33:35

Constantine
13.07.2018
18:34:17

Andrey
13.07.2018
18:36:34
То что Вы говорите примерами на godbolt звучит разумно — можно было бы сделать structured bindings так, как будно мы каждый компонент объявляем независимо. Но это бы тоже вызывало некоторый когнитивный диссонанс, потому что была бы разница между
auto & x = ..., & y = ...; и
auto & [x, y] = ....

Constantine
13.07.2018
18:37:49
только сигнатура метода const

Aidar
13.07.2018
18:39:27
причем можно было сделать decltype(auto) [y] накрайняк
ну такто есть auto&&[]

Constantine
13.07.2018
18:41:06
да
auto [x, &y] тоже безумно логично в контексте

Andrey
13.07.2018
18:41:19

Constantine
13.07.2018
18:41:29
лямбда-захватов
а expression по-прежнему на auto&& всегда получать
пздц они там поехавшие
хм... а может, писать не
for (auto & [a, b] : zip_view(va, vb))
а
for (auto & [a, b] : zip(std::ref(va), std::ref(vb))

Google

Aidar
13.07.2018
18:46:17
и ref проифать?

Constantine
13.07.2018
18:46:29
std::reference_wrapper ифать, угу
&vector нельзя, указатели итерируемые
не будет на vector<int> some[2]; работать
хотя стоп. std::begin(T*) нельзя же

Aidar
13.07.2018
18:48:14
ты не можешь терять там тип

Constantine
13.07.2018
18:48:21

Andrey
13.07.2018
18:48:44

Constantine
13.07.2018
18:48:47

Aidar
13.07.2018
18:48:57
на массив? тип всрал

Constantine
13.07.2018
18:48:58
т.е. zip_view требует ссылку

Aidar
13.07.2018
18:49:23
ты можешь взять begin только пока не потерял тип

Constantine
13.07.2018
18:49:43
хм... хочешь сказать *std::addressof(x) это не тривиальный оператор?

Aidar
13.07.2018
18:50:33
я хочу сказать что надо брать begin(T (&)[N])

Constantine
13.07.2018
18:51:00
я требую, чтобы в случае ref-итерации мне передали addressof целевого

Aidar
13.07.2018
18:51:59
char va[15];
я не понял
zip(&va, &va)

Andrey
13.07.2018
19:01:50
вопрос неоднозначный:
https://godbolt.org/g/oxKnsT
Короче clang и (gcc) просто обманывают: в unevaluated контексте они считают x не константным (и foo(x) резолвится в #1) а в обычном — константным (и foo(x) резолвится в #2).
https://godbolt.org/g/RFksHu

Constantine
13.07.2018
19:05:48