problemas mem_fun_ref
-
09-09-2019 - |
Pergunta
Estou tendo dificuldade para descobrir mem_fun_ref
. Eu tenho que admitir, eu costumo usar functors para este tipo de coisa, uma vez que pode ser embutido em velocidade e lucro. No entanto, este código não vai ser um gargalo e então eu queria experimentar essa coisa.
Aqui está um exemplo do que eu quero fazer. Eu sei que existem outras maneiras de fazê-lo. Eu não quero usar copy
, eu não quero usar funções de membro de gama, eu não quero usar um back_inserter
. Quero especificamente para usar mem_fun_ref
. Este é apenas um exemplo simples, o caso real é muito mais complicado. Dito isto, eu realmente não sei por que isso é errado, mas eu não estou familiarizado com mem_fun_ref
ou mem_fun
.
Aqui está o que eu quero trabalho:
#include <list>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
int main()
{
list<int> a;
a.push_back(1);
a.push_back(2);
a.push_back(3);
vector<int> b;
// should work like magic!
for_each(a.begin(), a.end(), bind1st(mem_fun_ref(&vector<int>::push_back), b));
}
Mas eu fico 3 erros:
1>c:\program files\microsoft visual studio 9.0\vc\include\functional(276) : error C2529: '_Right' : reference to reference is illegal
1>c:\program files\microsoft visual studio 9.0\vc\include\functional(281) : error C2529: '_Right' : reference to reference is illegal
1>c:\program files\microsoft visual studio 9.0\vc\include\functional(282) : error C2535: 'void std::binder1st<_Fn2>::operator ()(const int &(&)) const' : member function already defined or declared
1> with
1> [
1> _Fn2=std::mem_fun1_ref_t<void,std::vector<int>,const int &>
1> ]
1> c:\program files\microsoft visual studio 9.0\vc\include\functional(276) : see declaration of 'std::binder1st<_Fn2>::operator ()'
1> with
1> [
1> _Fn2=std::mem_fun1_ref_t<void,std::vector<int>,const int &>
1> ]
reference to reference is illegal
me faz pensar que a função precisa de ter um parâmetro por valor. Mas, claro, isso não é possível alterar no vector
, e não é possível alterá-lo no meu código também. Existe uma simples mudança de chegar a este trabalho? Eu preciso de uma solução que é um-liner 1.
Solução
Apenas uso bind
. As versões mem_fun
são muito difíceis.
for_each(a.begin(), a.end(),
boost::bind(&vector<int>::push_back, boost::ref(b), _1));
Outra forma que não requer o uso de ref
está a passar um ponteiro para o vetor a ser modificado:
for_each(a.begin(), a.end(),
boost::bind(&vector<int>::push_back, &b, _1));
Outras dicas
Este problema foi explicado em "Estilo Excepcional C ++" por Herb Sutter, página 28-30. Um provavelmente não pode criar com segurança um ponteiro para um método vector<int>::push_back
como é preciso ter certeza de assinatura exata da função de membro, que pode não ser óbvio mesmo para vector<int>::push_back
na biblioteca padrão. Isto porque (na Biblioteca Padrão):
- A assinatura da função de membro com parâmetros padrão pode ser substituído por "dois ou mais função de membro assinaturas com o comportamento equivalente.
- A assinatura da função membro pode ter parâmetros inadimplentes adicionais.
No final, Herb Sutter aconselhável que
- Use mem_fun, não apenas com a biblioteca padrão
- usar ponteiros para funções de membro, não apenas com a biblioteca padrão
Eu sei que você disse que não quer o uso back_inserter
, provavelmente porque você tenha dado apenas simplificado exemplo de código.
Para qualquer outra pessoa perguntando como fazer exatamente o que você está tentando fazer, e feliz para usá-lo, o uso back_inserter
:
std::copy(a.begin(), a.end(), std::back_inserter(b));