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

Использование bind2nd - C++

Восстановить пароль Регистрация
 
 
andrejap
13 / 13 / 1
Регистрация: 21.04.2013
Сообщений: 245
23.06.2014, 00:22     Использование bind2nd #1
Доброй ночи! Помогите, пожалуйста, разобраться с биндерами.
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
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
#include <algorithm>
#include <iterator>
#include <functional>
#include <vector>
#include <cstdlib>
#include <ctime>
 
using namespace std;
 
typedef const int first_argument_type;
typedef const int second_argument_type;
typedef bool result_type;
 
result_type isBuzz(first_argument_type v, second_argument_type d);
 
int main() {
    srand(time(0));
    vector<int> vi(15);
    for (auto& x : vi) x = rand() % 100;
 
    //putting out unchanged values
    for (const auto& x : vi) cout << x << endl;
 
    //setting adapter
    const int d = 5;
    for_each(vi.cbegin(), vi.cend(), bind2nd(isBuzz(), d));
 
    //putting out changed values
    cout.fill ('_');
    for (const auto& x : vi) {
        cout.width(5);
        cout << x << endl;
    }
    return 0;
}
 
result_type isBuzz(first_argument_type v, second_argument_type d) {
    if (v%d == 0)
        return true;
    else
        return false;
}
Хотелось бы понять как правильно "тайпдефить" адаптируемую функцию?.. И поясните ошибку, плз:
clang++ -std=c++11 -O2 16_0.cxx
16_0.cxx:27:43: error: no matching function for call to 'isBuzz'
for_each(vi.cbegin(), vi.cend(), bind2nd(isBuzz(), d));
^~~~~~
16_0.cxx:15:13: note: candidate function not viable: requires 2 arguments, but 0 were provided
result_type isBuzz(first_argument_type v, second_argument_type d);
^
1 error generated.


Добавлено через 5 минут
А, итераторы уже сообразил - нужно begin() и end()! Но это все-равно сути не решает.
upd2. Уф, и первый аргумент должен быть не-const. Исправил.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
23.06.2014, 00:35     Использование bind2nd #2
Цитата Сообщение от andrejap Посмотреть сообщение
C++
1
bind2nd(isBuzz(), d)
C++
1
bind2nd(ptr_fun(isBuzz), d)
+ раз уж пользуетесь стандартом C++11, то стоит знать, что std::bind2nd и пр. объявлены deprecated (т.е. устаревшими) и предполагается использование std::bind:
C++
1
2
using namespace std::placeholders;
std::bind(isBuzz, _1, d)
Добавлено через 11 минут
Добавлю (на всякий случай), что во-первых, запись isBuzz() подразумевает, что происходит вызов функции (что тут не нужно), во-вторых, логика std::bind2nd предполагает, что первым аргументом является функциональный объект (с доступным operator () (first_argument_type, second_argument_type)), поэтому необходим wrapper (обёртка) указателя на функцию в функциональный объект (ptr_fun его генерирует).
andrejap
13 / 13 / 1
Регистрация: 21.04.2013
Сообщений: 245
23.06.2014, 00:44  [ТС]     Использование bind2nd #3
gray_fox, спасибо за помощь! Файл скомпилировался, но у меня еще возник вопрос: в коде, который приведен ниже, я сделал так:
C++
1
auto binded_isBuzz = bind(isBuzz, _1, d);
Что за возвращаемый тип там должен быть? Почему bool нельзя?
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
33
34
35
36
37
38
39
40
#include <iostream>
#include <algorithm>
#include <iterator>
#include <functional>
#include <vector>
#include <cstdlib>
#include <ctime>
 
using namespace std;
using namespace std::placeholders;
bool isBuzz(int& v, const int& d);
 
int main() {
    srand(time(0));
    vector<int> vi(15), vii(15);
    for (auto& x : vi) x = rand() % 100;
 
    //putting out unchanged values
    for (const auto& x : vi) cout << x << endl;
 
    //setting adapter
    const int d = 5;
    auto binded_isBuzz = bind(isBuzz, _1, d);
    copy_if(vi.begin(), vi.end(), vii.begin(), binded_isBuzz);
 
    //putting out changed values
    cout.fill ('_');
    for (const auto& x : vii) {
        cout.width(5);
        cout << x << endl;
    }
    return 0;
}
 
bool isBuzz(int& v, const int& d) {
    if (v%d == 0)
        return true;
    else
        return false;
}
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
23.06.2014, 00:51     Использование bind2nd #4
Цитата Сообщение от andrejap Посмотреть сообщение
Что за возвращаемый тип там должен быть? Почему bool нельзя?
Не понял; если интересует возвращаемый тип std::bind, то это будет некий функциональный объект, конкретный тип которого нет смысла знать (предполагается in place использование), который будет иметь примерно следующий оператор вызова функции:
C++
1
2
3
4
template<typename T>
constexpr bool operator(T && secondArgument) const {
   return holdedCallable(holdedFirstArgument, std::forward<T>(secondArgument));
}
andrejap
23.06.2014, 00:55  [ТС]
  #5

Не по теме:


Вот такой вот тип typeinfo::name() показывает:
St5_BindIFPFbRiRKiESt12_PlaceholderILi1EEiEE
)
А что это может быть?


p.s.

Цитата Сообщение от gray_fox Посмотреть сообщение
если интересует возвращаемый тип std::bind
да

Ага - ясно теперь!) Вы мне очень помогли! Благодарю!

gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
23.06.2014, 00:58     Использование bind2nd #6
Т.е. обычно это предполагается использовать так:
C++
1
 copy_if(vi.begin(), vi.end(), vii.begin(), bind(isBuzz, _1, d));

Не по теме:

Добавлено через 2 минуты

Цитата Сообщение от andrejap Посмотреть сообщение
А что это может быть?
Да х его з) Если интересно, там с помощью шаблонов классов рекурсивно "собирается" тип функционального объекта с нужными свойствами, его конкретный тип в стандарте не специфицирован, да и, вообще говоря, смысла знать этот конкретный тип нет.

andrejap
13 / 13 / 1
Регистрация: 21.04.2013
Сообщений: 245
23.06.2014, 01:02  [ТС]     Использование bind2nd #7
gray_fox, да - так предполагается. Но мой вопрос относительно возвращаемого типа адаптора связан с тем, что как-то не хочу применять повсеместно auto, пока не буду знать точно, что выводится там автоматически. Спросил, чтобы разобраться что же там, если не bool.
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
23.06.2014, 01:22     Использование bind2nd #8
Цитата Сообщение от andrejap Посмотреть сообщение
Но мой вопрос относительно возвращаемого типа адаптора связан с тем, что как-то не хочу применять повсеместно auto, пока не буду знать точно, что выводится там автоматически.
Там смысл в том, что ты будешь знать какими свойствами обладает адаптор (callable, сколько и каким образом передаются аргументы), но какой конкретный тип будет иметь этот адаптор тебе знать не надо; на разных компиляторах даю оценку 146% он будет совершенно разный. Если интересна реализация, то смотри исходники STL либо boost::bind (сразу скажу, вся эта "магия" относительно проста но здесь синтаксис С++ и правила оформления кода не для слабонервных.

Добавлено через 8 минут
+ учитывая сказанное, если ты собираешься сохранить результат std::bind, то обязательно используй auto в качестве спецификатора типа, т.к. возвращаемый тип не специфицирован стандартом языка.

Добавлено через 4 минуты
Цитата Сообщение от andrejap Посмотреть сообщение
Спросил, чтобы разобраться что же там, если не bool.
Там должен быть (если не запамятовал) не bool, а callable (вызываемая "сущность"), которая имеет тип возвращаемого значения, неявно приводимого к bool.
andrejap
13 / 13 / 1
Регистрация: 21.04.2013
Сообщений: 245
23.06.2014, 01:30  [ТС]     Использование bind2nd #9
Цитата Сообщение от gray_fox Посмотреть сообщение
Если интересна реализация, то смотри исходники STL
Если бы знать, где тут они:
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mrx@1015bx-suse:~/sources/gcc-4.8.3> ls -a
.                   COPYING          libada        libquadmath         Makefile.def
..                  COPYING3         libatomic     libsanitizer        Makefile.in
ABOUT-NLS           COPYING3.LIB     libbacktrace  libssp              Makefile.tpl
boehm-gc            COPYING.LIB      libcpp        libstdc++-v3        MD5SUMS
ChangeLog           COPYING.RUNTIME  libdecnumber  libtool-ldflags     missing
ChangeLog.tree-ssa  depcomp          libffi        libtool.m4          mkdep
compile             fixincludes      libgcc        ltgcc.m4            mkinstalldirs
config              gcc              libgfortran   ltmain.sh           move-if-change
config.guess        .gitignore       libgo         lt~obsolete.m4      NEWS
config-ml.in        gnattools        libgomp       lto-plugin          README
config.rpath        include          libiberty     ltoptions.m4        symlink-tree
config.sub          INSTALL          libitm        ltsugar.m4          ylwrap
configure           install-sh       libjava       ltversion.m4        zlib
configure.ac        intl             libmudflap    MAINTAINERS
contrib             LAST_UPDATED     libobjc       maintainer-scripts
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
23.06.2014, 01:46     Использование bind2nd #10
Цитата Сообщение от andrejap Посмотреть сообщение
Если бы знать, где тут они:
Найди, где у тебя находится <functional> (find <your_g++_include_dir> -name functional) и проследи цепочку include-ов.

Добавлено через 5 минут
Например у меня (Винда + MinGW_4.8.0) определение std::bind находится в <functional>.
andrejap
13 / 13 / 1
Регистрация: 21.04.2013
Сообщений: 245
23.06.2014, 01:53  [ТС]     Использование bind2nd #11
gray_fox, ну эт я напамять помню: /usr/include/c++/functional .Днем посмотрю уже с компа, а то пишу со смарта.
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
23.06.2014, 01:57     Использование bind2nd #12

Не по теме:

Если что, MinGW - это "минимальный" порт для разработчика, который включает gcc/g++ порт под Windows.



Добавлено через 2 минуты
Цитата Сообщение от andrejap Посмотреть сообщение
ну эт я напамять помню: /usr/include/c++/functional
Смотри его, наверняка все определения в этом заголовочном файле; если нет, то смотри цепочки include-ов, они обычно имеют вполне понятные имена.
andrejap
13 / 13 / 1
Регистрация: 21.04.2013
Сообщений: 245
23.06.2014, 01:58  [ТС]     Использование bind2nd #13
gray_fox, mingw - это для cygwin или можно его и в разных ide использовать?
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
23.06.2014, 02:07     Использование bind2nd #14
andrejap, можно в разных IDE, MinGW - это минимальный порт (Cygwin его использует). Например, я использую на Винде NetBeans + MinGW_8.0 для личных проектов, Cygwin иметь для этого не обязательно, MinGW в базовой конфигурации даст тебе возможность использовать большинство языков, поддерживаемых GCC.
andrejap
13 / 13 / 1
Регистрация: 21.04.2013
Сообщений: 245
23.06.2014, 02:12  [ТС]     Использование bind2nd #15
gray_fox, использовать где? Не в NetBeans же? Я почему спрашиваю - саю использую netbeans; туда же (в netbeans) gccgo не подключишь? Или на windows такое прокатывает с netbeans+mingw?
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
23.06.2014, 02:18     Использование bind2nd #16
andrejap, если ты под Linux используешь NetBeans, наверняка ты используешь g++ (либо clang++), MinGW - это порт gcc (и, соответственно, g++) под Win.
andrejap
13 / 13 / 1
Регистрация: 21.04.2013
Сообщений: 245
23.06.2014, 02:25  [ТС]     Использование bind2nd #17
gray_fox, да, выбираю либо то, либо то. Просто из-за информативности вывода, на силенге он еще и цветной в терминале.

Спасибо большое за инфу! Узнал много новой информации! Доброй ночи!
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
23.06.2014, 02:30     Использование bind2nd #18
Цитата Сообщение от andrejap Посмотреть сообщение
Просто из-за информативности вывода, на силенге он еще и цветной в терминале.
Да, clang пока рулит в плане информативности + у них есть своя виртуальная машина, которая может пригодиться для разработки своих нативных\JIT языков; см. http://llvm.org/.
Jupiter
23.06.2014, 02:31
  #19

Не по теме:

Цитата Сообщение от andrejap Посмотреть сообщение
C++
1
2
3
4
if (v%d == 0)
* * * * return true;
* * else
* * * * return false;
C++
1
return v % d == 0;

MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.06.2014, 23:31     Использование bind2nd
Еще ссылки по теме:

C++ Непонятки с bind2nd
C++ Ошибка номер c2535 в адапторе bind2nd
C++ Забиндить второй аргумент функции, используя std::bind2nd

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

Или воспользуйтесь поиском по форуму:
andrejap
13 / 13 / 1
Регистрация: 21.04.2013
Сообщений: 245
23.06.2014, 23:31  [ТС]     Использование bind2nd #20
gray_fox, ага, вижу - в самом хедере определение есть:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  /**
   *  @brief Function template for std::bind.
   *  @ingroup binders
   */
  template<typename _Func, typename... _BoundArgs>
    inline typename
    _Bind_helper<__is_socketlike<_Func>::value, _Func, _BoundArgs...>::type
    bind(_Func&& __f, _BoundArgs&&... __args)
    {
      typedef _Bind_helper<false, _Func, _BoundArgs...> __helper_type;
      typedef typename __helper_type::__maybe_type __maybe_type;
      typedef typename __helper_type::type __result_type;
      return __result_type(__maybe_type::__do_wrap(std::forward<_Func>(__f)),
               std::forward<_BoundArgs>(__args)...);
    }
Возвращает какой-то __helper_type::type.
Интересно еще - что значит вторая строчка:
C++
1
inline typename
?
Yandex
Объявления
23.06.2014, 23:31     Использование bind2nd
Ответ Создать тему
Опции темы

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