Использование bind1st для метода, который принимает аргумент по ссылке
У меня есть такая структура:
struct A {
void i(int i) {}
void s(string const &s) {}
};
Теперь, когда я пробую это:
bind1st(mem_fun(&A::i), &a)(0);
bind1st(mem_fun(&A::s), &a)("");
Первая строка компилирует ОК, но вторая генерирует ошибку:
c:\program files (x86)\microsoft visual studio 10.0\vc\include\xfunctional(299): error C2535: 'void std::binder1st<_Fn2>::operator ()(const std::basic_string<_Elem,_Traits,_Ax> &) const' : member function already defined or declared
with
[
_Fn2=std::mem_fun1_t<void,A,const std::string &>,
_Elem=char,
_Traits=std::char_traits<char>,
_Ax=std::allocator<char>
]
c:\program files (x86)\microsoft visual studio 10.0\vc\include\xfunctional(293) : see declaration of 'std::binder1st<_Fn2>::operator ()'
with
[
_Fn2=std::mem_fun1_t<void,A,const std::string &>
]
c:\work\sources\exception\test\exception\main.cpp(33) : see reference to class template instantiation 'std::binder1st<_Fn2>' being compiled
with
[
_Fn2=std::mem_fun1_t<void,A,const std::string &>
]
В чем может быть проблема? Как я могу это исправить?
Edit:
Кажется, что любой ссылочный аргумент является проблемой. Поэтому, если я изменил метод i
на void i(int &i) {}
, я получаю аналогичную ошибку.
Ответы
Ответ 1
std:: bind1st и std:: bind2nd не принимают функторы, которые принимают ссылочные аргументы, потому что они сами формируют ссылки на эти аргументы. Вы можете
- используйте указатели для ваших входов функций вместо ссылок
- use boost:: bind
- принять стоимость выполнения копирования строки
Ответ 2
Проблема заключается в дефекте в спецификации библиотеки.
Взгляните на этот отчет об ошибке gcc и результирующее обсуждение: Ошибка 37811 - bind1st завершает работу с mem_fun с помощью ссылочного аргумента
С++ 03 не хватало возможностей для создания идеальной библиотеки связок. Эта проблема исправлена в С++ 11 с совершенной переадресацией и std:: bind.
Ответ 3
Посмотрите на это сообщение , как объясняются требования к параметрам шаблона.
Как вы уже предполагали, проблема с std::string является проблемой. Это не допустимый шаблонный параметр.
Ответ 4
Изменить ссылки указателями
#include <functional>
#include <string>
struct A {
void i(int i) {}
void s(const std::string *s) {}
};
int main(void)
{
A a;
std::bind1st(std::mem_fun(&A::i), &a)(0);
const std::string s("");
std::bind1st(std::mem_fun(&A::s), &a)(&s);
}