Форум программистов, компьютерный форум CyberForum.ru

По какой логике работают плейсхолдеры в данных примерах? - C++

Восстановить пароль Регистрация
 
tapochka
30 / 30 / 7
Регистрация: 25.04.2014
Сообщений: 413
18.11.2015, 23:56     По какой логике работают плейсхолдеры в данных примерах? #1
здравствуйте, подскажите пожалуйста по какой логике работают плейсхолдеры в данных примерах? что и куда они подставляют? вообще въехать не могу...
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
typedef transform<
      range_c<int,0,10>
    , plus<_1,_1>
    , back_inserter< vector0<> >
    >::type result;
 
typedef mpl::find_if
<
    some_sequence, 
    mpl::and_
    <
        boost::is_convertible<_1, int>, 
        mpl::not_<boost::is_same<_1, char>>, 
        mpl::not_<boost::is_float<_1>>
    >
>::type iter;
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.11.2015, 23:56     По какой логике работают плейсхолдеры в данных примерах?
Посмотрите здесь:

Непонятные условия в некоторых примерах C++
C++ Помогите разобраться с классе на примерах!
C++ Не работают функции удаления и добавления данных в класс
C++ CUDA на примерах
Учебник C++ по работе с массивами в примерах C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DrOffset
6458 / 3832 / 885
Регистрация: 30.01.2014
Сообщений: 6,627
19.11.2015, 08:24     По какой логике работают плейсхолдеры в данных примерах? #2
Цитата Сообщение от tapochka Посмотреть сообщение
подскажите пожалуйста по какой логике работают плейсхолдеры в данных примерах?
Подставляют очередной элемент последовательности.
Т.е. для каждого элемента будет проверяться условие is_convertible<elem, int> && !is_same<elem, char> && !is_float<elem>, где elem - это текущий элемент при переборе последовательности.
tapochka
30 / 30 / 7
Регистрация: 25.04.2014
Сообщений: 413
19.11.2015, 22:17  [ТС]     По какой логике работают плейсхолдеры в данных примерах? #3
Цитата Сообщение от DrOffset Посмотреть сообщение
Т.е. для каждого элемента будет проверяться условие
а не подскажете почему если написать так, то все нормально:
C++
1
2
3
4
5
typedef boost::mpl::find_if< hr::vec_t, boost::mpl::and_<
        boost::mpl::not_<boost::is_same<boost::mpl::placeholders::_, char>>,
        boost::mpl::not_<boost::is_float<boost::mpl::placeholders::_>>
    >
    >::type iter_t;
а так, то все валиться:
C++
1
2
3
4
5
typedef boost::mpl::find_if< hr::vec_t, boost::mpl::and_<
        boost::mpl::not_<boost::is_same<boost::mpl::placeholders::_2, char>>,
        boost::mpl::not_<boost::is_float<boost::mpl::placeholders::_2>>
    >
    >::type iter_t;
в чем принципиальная разница то?
DrOffset
6458 / 3832 / 885
Регистрация: 30.01.2014
Сообщений: 6,627
20.11.2015, 08:40     По какой логике работают плейсхолдеры в данных примерах? #4
Цитата Сообщение от tapochka Посмотреть сообщение
в чем принципиальная разница то?
Объясню на пальцах.
Вот представь себе такой код:
C++
1
2
3
for(auto & elem : sequence)
    if(check_elem(elem))
        return elem;
Вот elem в этом коде - это _1.
Теперь подумай, какое место тут займет _2? Если мы используем здесь _2, то это должен быть next(elem), т.е. следующий за elem. Но как тогда контролировать выход за пределы в случае последнего элемента? Да и смысл алгоритма этого не предполагает. В общем - это бессмысленно, поэтому запрещено.
_2, _3 и т.д. используются там, где есть несколько сразу доступных аргументов. Например при подстановке параметров функций. При поиске аргумент только один, текущий.
tapochka
30 / 30 / 7
Регистрация: 25.04.2014
Сообщений: 413
15.12.2015, 04:47  [ТС]     По какой логике работают плейсхолдеры в данных примерах? #5
DrOffset,
сорри что поднимаю прошлую тему, но можете объяснить в чем ошибка?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//сумма элементов вектора которые больше единицы
typedef vector_c<int, 1,1,1,2,5> vec_c_t;
typedef fold<vec_c_t, int_<0>, plus<placeholders::_,
                                                  if_<
                                                        less<
                                                              int_<1>, placeholders::_2
                                                          >,
                                                         next<placeholders::_1>,
                                                         placeholders::_1
                                                        >
                                               >
                >::type sum_t_1;
 
BOOST_STATIC_ASSERT((sum_t_1::value == 7));
притом, что каким-то боком случайно сделал это:
C++
1
2
3
4
5
typedef fold<vec_c_t, int_<0>, plus<placeholders::_,
                                               placeholders::_>
                            >::type sum_t;
 
BOOST_STATIC_ASSERT((sum_t::value == 10));
почему в последнем примере если заменить на _1, то все валится?
здесь еще больше запутался чем в первом посте
DiffEreD
 Аватар для DiffEreD
1420 / 757 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
15.12.2015, 16:30     По какой логике работают плейсхолдеры в данных примерах? #6
Попробуй так:
C++
1
2
3
4
typedef vector_c<int, 1,1,1,2,5> vec_c_t;
typedef fold<vec_c_t, int_<0>, plus<_1, if_<less<int_<1>, _2>, _2, _1> >>::type fold_t;
 
BOOST_STATIC_ASSERT((fold_t::value == 7));
Добавлено через 4 минуты
Цитата Сообщение от tapochka Посмотреть сообщение
почему в последнем примере если заменить на _1, то все валится?
C++
1
plus<_1, _1>
станет эквивалентным этому:
C++
1
plus<int_<0>, int_<0>>
что всегда дает int_<0>

Добавлено через 1 минуту
Так не валиться:
C++
1
2
typedef fold<vec_c_t, int_<0>, plus<_1, _1>>::type sum_t;
BOOST_STATIC_ASSERT((sum_t::value == 0));
tapochka
30 / 30 / 7
Регистрация: 25.04.2014
Сообщений: 413
15.12.2015, 22:48  [ТС]     По какой логике работают плейсхолдеры в данных примерах? #7
DiffEreD, большое спасибо за ответы... вот только не понимаю почему именно так должно быть. разъясните пожалуйста следущее:
вот есть алгоритм работы fold из книги, согласно которому он рекурсивно аккумулирует предыдущий результат с последующим, полученным уже из урезанной начальной последовательности
fold(Seq, Prev, BinaryOp) :=
if Seq is empty then:
Prev
else: // combine the first element with Prev
fold( // and process the rest recursively
tail(Seq),
BinaryOp(Prev, head(Seq)),
BinaryOp
)
согласно ему, на первом шаге итерации вашего алгоритма, который возвращает fold_t, у нас будет примерно следущее:
C++
1
2
3
4
5
6
7
8
fold<vector_c<1,1,2,5>,  //урезанный входной вектор
                    plus< int_<0>, 
                    if_<  less< int_<1>,  1 >,  //не понимаю почему placeholder_2 подставляет 1 
                         ... ,                                 //и что здесь подставляет placeholder _2 ?
                         ... >,                               // а здесь placeholder _1 ?
                    ...>,                                     //а здесь опять почему-то placeholder _1... что он здесь подставляет?
        binaryOp                                           //то же бинарное выражение 
>
вот, допустим, здесь понятно почему все верно компилится:
C++
1
2
3
4
5
6
typedef vector_c<int, 1, 1, 1, 2, 5> vec_c_t;
typedef vector_c<int, 1, 1, 1, 1, 1> vec_c_t1;
 
typedef transform<vec_c_t, vec_c_t1, plus<_1, _2>>::type trs;
 
BOOST_MPL_ASSERT((equal<vector_c<int, 2, 2, 2, 3, 6>, trs>));
_1 берет из первого вектора, _2 из второго и складываются... но в fold_t не понятно почему там _2 вообще берется...

так же и с sum_t... откуда там при замене на _1 вообще int_<0> берется?
DiffEreD
 Аватар для DiffEreD
1420 / 757 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
15.12.2015, 23:30     По какой логике работают плейсхолдеры в данных примерах? #8
_1 - это то что есть int_<0> на первой итерации шаблона
_2 - это элемент вектора на каждой итерации
C++
1
2
3
4
5
6
typedef fold<vec_c_t, 
            int_<0>, // _1
            plus<_1, if_<less<int_<1>, //_1 + >>
            _2>, // _2 - элемент vec_c_t
            _2, _1>  // << (_2 или _1)
            >>::type fold_t;
tapochka
30 / 30 / 7
Регистрация: 25.04.2014
Сообщений: 413
15.12.2015, 23:37  [ТС]     По какой логике работают плейсхолдеры в данных примерах? #9
Цитата Сообщение от DiffEreD Посмотреть сообщение
_1 - это то что есть int_<0> на первой итерации шаблона
_2 - это элемент вектора на каждой итерации
а почему не наоборот? вектор же стоит раньше чем int_<0>
DiffEreD
 Аватар для DiffEreD
1420 / 757 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
16.12.2015, 00:20     По какой логике работают плейсхолдеры в данных примерах? #10
Вроде бы так и есть, сам запутался. Вот так должно быть вернее:
C++
1
2
3
4
5
6
7
8
typedef vector_c<int, 10,0,0,2,5,3> vec_c_t;
typedef fold<vec_c_t,
            int_<0>,
            plus<_2, if_<less<int_<1>, _1>,
            _1, int_<0>>
            >>::type fold_t;
 
BOOST_STATIC_ASSERT((fold_t::value == 20));
tapochka
30 / 30 / 7
Регистрация: 25.04.2014
Сообщений: 413
16.12.2015, 00:28  [ТС]     По какой логике работают плейсхолдеры в данных примерах? #11
ну вот последний пример уже очерчивает контуры хоть какого-то понимания, благодарствую...
чтоб без вас делал...

только вот непонятно почему предыдущий пример компилился, но лучше тогда про это не думать
DiffEreD
 Аватар для DiffEreD
1420 / 757 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
16.12.2015, 11:03     По какой логике работают плейсхолдеры в данных примерах? #12
И все же снова неверно я написал. Судя по коду ниже получается что порядок заменителей такой как я и указал 8 посте (вместо less использовал greater):
Кликните здесь для просмотра всего текста
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
28
29
30
31
32
#include <iostream>
#include <boost/mpl/vector_c.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/greater.hpp>>
#include <boost/mpl/plus.hpp>
#include <boost/static_assert.hpp>
 
using namespace boost::mpl;
 
int main()
{
    typedef vector_c<int, 10,1,1,2,5,3,1,1,-2> vec_c_t;
    typedef fold<vec_c_t,
                int_<0>,
                plus<_1, if_<greater<_2, int_<1>>,
                _2, int_<0>>
                >>::type fold_t1;
 
    std::cout << fold_t1::value << "\n";
    BOOST_STATIC_ASSERT((fold_t1::value == 20));
 
    typedef fold<vec_c_t,
                int_<0>,
                plus<_2, if_<greater<_1, int_<1>>,
                _1, int_<0>>
                >>::type fold_t2;
 
    std::cout << fold_t2::value << "\n";
    BOOST_STATIC_ASSERT((fold_t2::value != 20));
}
Voivoid
 Аватар для Voivoid
580 / 256 / 12
Регистрация: 31.03.2013
Сообщений: 1,284
16.12.2015, 13:17     По какой логике работают плейсхолдеры в данных примерах? #13
Прежде чем заниматься хардкорным шаблонным мета-программированием имеет смысл изучить haskell, тогда многие вопросы сами отпадут. Без шуток. Плюсовые шаблоны - по сути функциональный язык программирования.

Добавлено через 1 минуту
Еще кстати имеет смысл посмотреть в сторону boost::hana, там многие вещи делаются полегче чем в boost::mpl
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.12.2015, 00:40     По какой логике работают плейсхолдеры в данных примерах?
Еще ссылки по теме:

В примерах 1-4 сформировать квадратную матрицу порядка N по заданному образцу: C++
Передача параметров в sprintf - объяснить разницу в двух примерах C++
C++ Разобраться с std::bind, плейсхолдеры

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

Или воспользуйтесь поиском по форуму:
tapochka
30 / 30 / 7
Регистрация: 25.04.2014
Сообщений: 413
17.12.2015, 00:40  [ТС]     По какой логике работают плейсхолдеры в данных примерах? #14
Цитата Сообщение от Voivoid Посмотреть сообщение
Прежде чем заниматься хардкорным шаблонным мета-программированием имеет смысл изучить haskell
да какой уж тут хардкор то... хардкор это boost.proto имхо

про hana лично я даже не слыхал
Yandex
Объявления
17.12.2015, 00:40     По какой логике работают плейсхолдеры в данных примерах?
Ответ Создать тему
Опции темы

Текущее время: 08:55. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru