2 votes

La déduction des arguments de modèle a échoué avec le paramètre de modèle par défaut

#include 
#include 

class MyBar {
public:
    void print() {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
};

template 
class Foo{
public:
    Foo(const char* name, const uint32_t i) {
        Bar b;
        b.print();
    }
};

int main(int argc, char** argv) {
    auto pFoo1 = new Foo("abc", 3);
}

Le compilateur m'a donné :

template_ctor.cpp: Dans la fonction ‘int main(int, char**)’ :
template_ctor.cpp:21:31: erreur: l'inférence d'argument de modèle de classe a échoué :
  auto pFoo1 = new Foo("abc", 3);
                               ^
template_ctor.cpp:21:31: erreur: aucun appel de fonction correspondant pour ‘Foo()’
template_ctor.cpp:14:2: note: candidat: template Foo(const char*, uint32_t)-> Foo
  Foo(const char* name, const uint32_t i) {
  ^~~
template_ctor.cpp:14:2: note:   déduction/substitution d'argument de modèle a échoué :
template_ctor.cpp:21:31: note:   le candidat attend 2 arguments, 0 fournis
  auto pFoo1 = new Foo("abc", 3);

Aussitôt que je mets <> après new Foo, cela compile.

Au début, je pensais que <> était obligatoire pour indiquer au compilateur d'utiliser le paramètre de modèle par défaut, mais ensuite j'ai remarqué que si je supprime const char* name et que je ne passe pas "abc", alors cela compile également.

Maintenant, je suis confus.

2voto

Barry Points 45207

Cela devrait compiler, et c'est essentiellement bug gcc 85883. Cela a été corrigé sur le tronc:

struct MyBar;

template 
class Foo{
public:
    Foo(const char* name, int i);
};

auto pFoo1 = new Foo("abc", 3);

L'exemple échoue sur gcc 8.2, mais compile sur 9.

0voto

Joachim Pileborg Points 121221

Le compilateur utilise les informations qu'il possède au moment de l'instanciation pour la déduction.

Dans le cas de new Foo("abc", 3), il ne dispose vraiment que des types d'argument du constructeur, aucun d'entre eux n'étant modélisé. Par conséquent, vous devez utiliser new Foo<>("abc", 3) pour indiquer explicitement qu'aucun type de template n'est spécifié et que le type par défaut doit être utilisé.

Cette utilisation existe en C++ depuis l'introduction des types d'arguments de template par défaut.

Si l'un des arguments du constructeur était du type de template, alors le compilateur devrait être en mesure de déduire le type de template à partir de cet argument.

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