Pourquoi est-ce que j'obtiens l'erreur "la référence à la fonction membre non statique doit être appelée":
<source>:35:19: error: reference to non-static member function must be called
list_.front().Set<Flags::First>(true);
~~~~~~~~~~~~~~^~~
<source>:40:10: note: in instantiation of member function 'List<int>::Set' requested here
list.Set();
^
<source>:13:8: note: possible target for call
void Set(bool value) {
^
1 error generated.
Compiler returned: 1
quand j'essaye de compiler ce code avec clang 7.0.0 ?
#include <iostream>
#include <list>
using namespace std;
enum class Flags : uint8_t {
First = 1,
Second = 2
};
class Header {
public:
template <Flags flag>
void Set(bool value) {
flags_ = static_cast<Flags>(
value
? (static_cast<uint8_t>(flags_) | static_cast<uint8_t>(flag))
: (static_cast<uint8_t>(flags_) & (~static_cast<uint8_t>(flag))));
}
private:
Flags flags_{};
};
template <class T>
class List {
public:
void Set();
private:
std::list<Header> list_;
};
template <class T>
void List<T>::Set() {
list_.front().Set<Flags::First>(true);
}
int main() {
List<int> list;
list.Set();
return 0;
}
Voir ici : https://godbolt.org/z/KXttBb
Nous pouvons expliquer à la fois comment diagnostiquer cela et comment et pourquoi le correctif fonctionne.
<source>:35:19: error: reference to non-static member function must be called
OK, donc clang pense que quelque chose nomme une fonction membre non statique et que l'expression dans laquelle vous l'utilisez n'est pas un appel de fonction :
list_.front().Set<Flags::First>(true);
~~~~~~~~~~~~~~^~~
Il nous dit assez explicitement qu'il reconnaît Set
comme une fonction membre non statique, mais il pense que ce Set<Flags::First>(true)
n'est pas un appel de fonction.
Évidemment, c'est exactement la bonne syntaxe pour appeler un modèle de fonction, donc le problème est que clang n'est pas traité Set
comme un modèle de fonction.
À ce stade, lisez définitivement la question liée dans les commentaires ci-dessus et la réponse acceptée .
...
Bon, maintenant que vous avez lu cela, il est évident qu'il Set
s'agit d'un nom de fonction dépendant, et nous pouvons résoudre le problème en ajoutant template
comme ceci :
list_.front().template Set<Flags::First>(true);
mais cela laisse encore ouverte la question de savoir pourquoi le nom est dépendant. Je veux dire, en lisant le code, nous savons qu'il list_.front()
doit avoir le type Header&
, n'est-ce pas ?
Essayons donc de l'écrire explicitement :
Header &front = list_.front();
front.Set<Flags::First>(true);
et nous voyons (toujours avec clang 8 ou 9) que cela fonctionne maintenant sans le supplément template
. Si vous écrivez auto &front
, le problème revient.
FWIW, cela apparaît dans clang 8 et 9, mais disparaît dans clang 10, et ne semble jamais se produire dans GCC. Donc, c'est peut-être un bug, mais au moins vous savez maintenant comment le diagnostiquer et comment le contourner.
Cet article est collecté sur Internet, veuillez indiquer la source lors de la réimpression.
En cas d'infraction, veuillez [email protected] Supprimer.
laisse moi dire quelques mots