Re[6]: Универсальная прокси-функция.
От: T4r4sB Россия  
Дата: 29.09.15 14:31
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Не разглядел emplace_back и make_shared в исходном сообщении. Старею?


Да, они там действительно не написаны в явном виде.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[15]: Универсальная прокси-функция.
От: Кодт Россия  
Дата: 29.09.15 14:51
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Да фиг знает, чёто такое, но это не сработает


Конечно, такое не сработает, потому что тут получается вывод типов сразу с двух сторон:
— из фактического типа аргумента
— из требований к аргументу, взятых из базы
А это запрещено стандартом.

Если отвлечься от конструктора, то решение именно так и выглядит
bar(X&);
bar(const Y&);
bar(volatile Z&);


template<class T> auto foo( T with cv-qualifiers etc & t ) -> sfinae if fits to bar(t) then void
{ bar(t); }

template<class T> auto foo( T with another cv-qualifiers etc & t ) -> sfinae if fits to bar(t) then void
{ bar(t); }


Конечно, если foo имеет много аргументов, это будет комбинаторный взрыв.

Но можно прибегнуть к частичному применению — т.е. заменить foo(T&&,U&&,V&&) на foo.start(T&&).and(U&&).and(V&&).go().
Каждая промежуточная функция унарная, сможет разобраться с двумя (или четыремя, если ещё volatile) вариантами и заначить правильную ссылку с правильным типом.

А превратить кортеж в серию вызовов — это boost preprocessor. Там даже основной тип для вариадиков — это именно sequence, (t)(u)(v).
Будет FOO(t,u,v,etc...) превращаться в foo(t)(u)(v)(etc...).go()

Ну или выбросить старый компилятор... Но это, как я понимаю, не вариант.
Перекуём баги на фичи!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.