0Pricing
C++ Academy · Aula

std::move e std::forward

Converta lvalues em rvalues com std::move e preserve a categoria de valor com std::forward

std::move e std::forward é uma aula grátis de C++ Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de C++ Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de C++ Academy inclui 4 aulas no total.

Dois primos, funções diferentes

std::move e std::forward são conversões realizadas em tempo de compilação. Parecem semelhantes, mas resolvem problemas diferentes.

std::move: sempre converte para rvalue

std::move(x) converte incondicionalmente x em uma referência rvalue. A função que recebe o valor pode então apropriar-se de seus recursos.

std::string s = "Hello";
std::string t = std::move(s);   // move-constructs t from s
// s is now in a valid-but-unspecified state

Quando usar a movimentação

Use std::move em:

  • Construtores de movimentação e operadores de atribuição por movimentação
  • Ao retornar uma variável local quando quiser forçar uma movimentação (raramente necessário — o RVO geralmente se aplica)
  • Ao passar uma variável local de que você não precisa mais para uma função consumidora

Implementação de std::move

É apenas um static_cast disfarçado:

template <typename T>
typename std::remove_reference<T>::type&& move(T&& t) noexcept {
    return static_cast<typename std::remove_reference<T>::type&&>(t);
}

std::forward: preserva a categoria

Em um modelo que usa uma referência de encaminhamento (T&&), std::forward<T>(x) converte x novamente para sua categoria original (lvalue ou rvalue). É usado para o encaminhamento perfeito.

template <typename T>
void wrapper(T&& arg) {
    target(std::forward<T>(arg));  // forwards as lvalue or rvalue depending on T
}

Por que o encaminhamento é necessário

Dentro do modelo, o parâmetro tem um nome — o que o torna um lvalue, mesmo que o chamador tenha passado um rvalue. std::forward recupera a categoria original.

Sem std::forward

Sem forward, todo argumento seria passado como lvalue dentro do wrapper, anulando qualquer semântica de movimentação pretendida pelo chamador.

template <typename T>
void wrapper(T&& arg) {
    target(arg);    // always lvalue — wrong
}

Sempre especifique o parâmetro de modelo para forward

std::forward<T> exige o argumento de modelo explícito. Sem ele, o comportamento estaria incorreto.

Exemplo de encaminhamento perfeito

Uma função fábrica que encaminha argumentos do construtor preserva as distinções entre rvalue e lvalue para obter eficiência.

template <typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args) {
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

Mova apenas uma vez

Cada objeto deve ser movido no máximo uma vez. Depois da movimentação, ele fica em um estado válido, mas não especificado — normalmente, você o reatribui ou o destrói. Usar um objeto do qual foi feita uma movimentação sem reatribuí-lo primeiro pode causar erros sutis.

Regras práticas

Modelo mental rápido:

  • Você tem um tipo concreto e quer movê-lo → std::move
  • Você tem um parâmetro de modelo e quer preservar a categoria → std::forward<T>

Verificação rápida

Dentro de uma função de modelo com o parâmetro T&& arg, como encaminhar arg preservando sua categoria lvalue/rvalue?

Recapitulação

std::move faz uma conversão incondicional para rvalue — use-o em objetos concretos dos quais deseja apropriar-se dos recursos. std::forward<T> preserva a categoria de valor dentro de modelos genéricos — use-o para o encaminhamento perfeito.

Perguntas Frequentes

A aula “std::move e std::forward” é grátis?

Sim — o texto completo de “std::move e std::forward” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de C++ Academy, atualize para CoddyKit PRO. O curso de C++ Academy inclui 4 aulas no total.

O que vou aprender em “std::move e std::forward”?

Converta lvalues em rvalues com std::move e preserve a categoria de valor com std::forward Você pratica C++ Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar C++ Academy?

Nenhuma experiência prévia é necessária. C++ Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.

Quanto tempo leva a aula “std::move e std::forward”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de C++ Academy?

Sim. Cada aula de C++ Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Lvalue versus rvalue: a distinção
  2. Referências rvalue e a sintaxe &&
  3. std::move e std::forward
  4. Construtores de movimento e atribuição por movimento
← Voltar para C++ Academy