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.

Foi útil?

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):

  1. 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.
  2. A assinatura da função membro pode ter parâmetros inadimplentes adicionais.

No final, Herb Sutter aconselhável que

  1. Use mem_fun, não apenas com a biblioteca padrão
  2. 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));

Dito isto, há sempre other_mem_fun, que eu cozinhei antes que eu sabia sobre impulso. Este poderia caber.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top