Erreur lors de l'utilisation de std::make_unique sur une structure

Le problème exposé dans ce sujet a été résolu.

Salut à tous,

Aujourd’hui, un lecteur du livre C++ m’a écrit un mail pour me signaler une erreur dans le code source suivant.

#include <memory>

struct A
{
  int entier;
  double reel;
};

int main()
{
  // Sur un type natif.
  auto handle_int { std::make_unique<int>(42) };

  // Sur un type que nous avons nous-mêmes défini.
  auto handle_a { std::make_unique<A>(42, 3.1415) };

  // La mémoire est automatiquement libérée, 'handle_a' ne gère plus rien.
  handle_int = nullptr;

  // 'handle_a' est de nouveau propriétaire d'une ressource de type 'int'.
  handle_int = std::make_unique<int>(0);

  return 0;
}

De son côté, il obtient l’erreur suivante (il ne m’a pas précisé le compilateur ni les options de compilation, seulement qu’il est sous Linux).

unique_ptr.h:827:30: error: new initializer expression list treated as compound expression [-fpermissive]
     { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }

Je suis alors allé sur Wandbox pour tester et j’ai remarqué qu’avec GCC 12 en C++20, ce code compile très bien alors que Clang 13 me sort l’erreur suivante (qui n’est pas la même).

/opt/wandbox/clang-head/include/c++/v1/__memory/unique_ptr.h:725:32: error: no matching constructor for initialization of 'A'
    return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...));
                               ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
prog.cc:15:24: note: in instantiation of function template specialization 'std::make_unique<A, int, double>' requested here
  auto handle_a { std::make_unique<A>(42, 3.1415) };
                       ^
prog.cc:3:8: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided
struct A
       ^
prog.cc:3:8: note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 2 were provided
prog.cc:3:8: note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 2 were provided
1 error generated.

Est-ce que le problème vient de Clang qui n’implémenterait pas un point de la norme C++20 correctement ? Ou bien serait-ce GCC qui aurait tord ?

En tout cas, les deux compilateurs ne compilent pas en C++17, ce qui me semblerait normal. Il me semble par contre qu’il compile avec le compilateur de Visual Studio 2019 en mode Dernière norme (donc C++17 et déjà plusieurs points de C++20).

Merci d’avance à tous pour vos éclaircissements.

informaticienzero

Je dois avouer n’avoir jamais testé le code de la ligne 15. C’est une forme d’agreggat-initialisation mais dans un make_unique ?

Par curiosité, j’ai testé avec l’implémentation de make_unique proposée dans cppreference. Ca compile avec GCC mais pas avec Clang. Donc ca laisse penser que c’est bien dans le support du langage et pas dans l’implémentation de la STL.

EDIT : j’ai demandé sur le discord NaN et Alairion a donné l’explication. Cette fonctionnalité est bien nouvelle en C++20 et c’est supporté par GCC et pas par Clang. Merci a lui.

+1 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte