Pergunta

É necessário me usar std::function mas eu não sei o que a seguinte sintaxe significa.

std::function<void()> f_name = []() { FNAME(); };

Qual é o objetivo de std::function?É para fazer um ponteiro para uma função?

Foi útil?

Solução

std::function é um tipo de apagamento do objeto.Isso significa que ele apaga os detalhes de como algumas operações de acontecer, e fornece um uniforme de tempo de execução de interface para eles.Para std::function, o principal1 operações de copiar/mover, a destruição e a 'invocação' com operator() -- a 'função como operador de chamada de'.

Em menos obtusos inglês, significa que std::function pode conter quase qualquer objeto que funciona como um ponteiro de função em como você chamá-lo.

A assinatura suporta passa dentro de parênteses em ângulo: std::function<void()> leva zero argumentos e retorna nada. std::function< double( int, int ) > leva dois int argumentos e retorna double.Em geral, std::function suporta o armazenamento de qualquer função como objeto cujos argumentos podem ser convertidos-a partir de sua lista de argumentos, e cujo valor de retorno pode ser convertido para o valor de retorno.

É importante saber que std::function e lambdas são diferentes, se compatível, animais.

A próxima parte da linha é um lambda.Esta é uma nova sintaxe em C++11 para adicionar a capacidade de escrever de uma função simples como objetos-objetos que podem ser invocados com ().Tais objetos podem ser do tipo apagados e armazenados em um std::function ao custo de alguns tempo de execução de sobrecarga.

[](){ code } em particular, é uma verdade simples lambda.Ele corresponde a este:

struct some_anonymous_type {
  some_anonymous_type() {}
  void operator()const{
    code
  }
};

um exemplo do acima simples pseudo-tipo de função.Uma classe real, como o acima é "inventado" pelo compilador, com uma implementação definido um nome exclusivo (muitas vezes incluindo símbolos que nenhum tipo definido pelo usuário pode conter) (não sei se é possível que você pode seguir o padrão sem inventar um tal de classe, mas cada compilador que eu conheço, na verdade, cria a classe).

O total lambda sintaxe se parece com:

[ capture_list ]( argument_list )
-> return_type optional_mutable
{
  code
}

Mas em muitas partes pode ser omitido ou deixado em branco.O capture_list corresponde tanto o construtor da resultante de tipo anônimo e suas variáveis de membro, o argument_list os argumentos da operator(), e o tipo de retorno o tipo de retorno.O construtor do lambda instância também é magicamente chamado quando a instância é criada com o capture_list.

[ capture_list ]( argument_list ) -> return_type { code }

basicamente, torna-se

struct some_anonymous_type {
  // capture_list turned into member variables
  some_anonymous_type( /* capture_list turned into arguments */ ):
    /* member variables initialized */
  {}
  return_type operator()( argument_list ) const {
    code
  }
};

Observe que na modelo argumentos foram adicionados para lambdas, e que não foi abordado acima.

[]<typename T>( std::vector<T> const& v ) { return v.size(); }

1 Além disso, ESTE é armazenado (typeid), e o elenco-de-volta-ao-original-tipo de operação está incluído.

Outras dicas

Vamos quebrar a linha de distância:

std::função

Esta é uma declaração de uma função sem parâmetros e retornar nenhum valor.Se a função retornou um int, ele teria esta aparência:

std::function<int()>

Da mesma forma, se ele teve um parâmetro int assim:

std::function<int(int)>

Eu suspeito que seu principal confusão é a próxima parte.

[]() { FNAME(); };

O [] parte é chamada de uma captura de cláusula.Aqui você coloca variáveis que são locais para a declaração de sua lambda, e que pretende ser disponível dentro a função lambda si.Este é dizendo "eu não quero nada para ser capturado".Se isto estava dentro de uma definição de classe e você queria que a classe a ser disponível para o lambda, você pode fazer:

[this]() { FNAME(); };

A próxima parte, é a parâmetros sendo passados para o lambda, exatamente o mesmo como se fosse uma função normal.Como mencionado anteriormente, std::function<void()> é uma assinatura apontando para um método que leva sem parâmetros, de modo que este está vazio também.

O resto é o corpo de lambda em si, como se de uma função normal, o que podemos ver apenas chama a função FNAME.

Outro Exemplo

Vamos dizer que você tinha a seguinte assinatura, que é algo que pode somar dois números.

std::function<int(int, int)> sumFunc;

Agora poderíamos declarar uma lambda assim:

sumFunc = [](int a, int b) { return a + b; };

Não sei se você estiver usando o MSVC, mas aqui está um link de qualquer forma, para a lamda sintaxe de expressão:

http://msdn.microsoft.com/en-us/library/dd293603.aspx

Lambdas com capturas (lambdas com estado) não podem ser atribuídos um ao outro, pois eles têm tipos únicos, mesmo que pareçam exatamente iguais. Para poder armazenar e passar por Lambdas com capturas, podemos usar "std :: function"Para manter um objeto de função construído por uma expressão de lambda. Basicamente"std :: function"É capaz de atribuir funções lambda a diferentes estruturas de conteúdo a um objeto de função lambda.

Exp:

auto func = [](int a){
 cout << "a:" << a << endl;
};
func(40);
//
int x = 10;
func = [x](int a){ //ATTENTION(ERROR!): assigning a new structure to the same object
 cout << "x:" << x << ",a:" << a << endl;
};
func(2);

Portanto, o uso acima estará incorreto. Mas se definirmos um objeto de função com "std :: function":

auto func = std::function<void(int)>{};
func = [](int a){
  cout << "a:" << a << endl;
};
func(40);
//
int x = 10;
func = [x](int a){ //CORRECT. because of std::function
  //...
}; 

int y = 11;
func = [x,y](int a){ //CORRECT
 //...
}; 
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top