8 votes

En C++, puis-je déplacer quelque chose hors d'un std::variant ?

J'ai une classe d'emballage de ressources qui n'est pas copiable, mais qui est mobile. Quelque chose comme ceci (pseudeocode)

class Wrapper {
  SomeResource* m_handle = nullptr;
public:
  Wrapper(const Wrapper&) = delete;
  Wrapper& operator=(const Wrapper&) = delete;

  Wrapper(SomeResource* handle) : m_handle(handle) { }
  Wrapper(Wrapper&& other) {
    std::swap(m_handle, other.m_handle);
  }
}

Tout cela est bien beau, mais j'en ai plusieurs, et j'ai une fonction qui analyse certaines données et renvoie SOIT un wrapper, SOIT un wrapper alternatif. J'ai pensé à utiliser std::variant pour exprimer cela dans une valeur de retour. Par exemple

std::variant<Wrapper, AlternativeWrapper> LoadData(void* bytes, size_t len)
{ ... }

Je peux écrire cette fonction, et tout se compile. C'est-à-dire que je construis un Wrapper dans la fonction LoadData, puis je peux le déplacer dans la variante qui est ensuite retournée.

Mais d'un autre côté, lorsque je veux récupérer la valeur, j'obtiens cette erreur (MSVC2019)

error C2280: 'Wrapper::Wrapper(const Wrapper&)': attempting to reference a deleted function

Mon code ressemble à ceci.

auto result = LoadData(bytes, len);
std::get<Wrapper>(result);

C'est logique puisque le résultat est toujours là, mais alors comment puis-je y accéder ?

7voto

Orion Edwards Points 54939

Oups, j'ai compris ça deux minutes après avoir posté la question.

Vous pouvez std::move la variante dans std::get .

auto v = LoadData(bytes, len);
std::get<Wrapper>(std::move(v));

Ou alors, il suffit de le mettre en ligne pour que la variante devienne une valeur temporaire.

std::get<Wrapper>(LoadData(bytes, len));

[Mise à jour :] J'avais dit à l'origine que std::move détruisait la variante originale, mais on m'a corrigé à juste titre en me disant que ce n'était pas le cas... cependant, ce qui se passe, c'est que le wrapper à l'intérieur de la variante est détruit lorsqu'il est déplacé, ce qui est attendu

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X