Diese Frage ist ein Follow-up von Moving a member function from base class to derived class breaks the program for no obvious reason (dies ist ein gutes Beispiel dafür, warum soll man using namespace std;
nicht verwenden)Matrizenabhängiger Basiselement behoben ist nicht richtig
, wo die Antworten von this->
eineine abhängigen Vorlagennamen qualifizieren vorschlagen (was in der Tat der Weg ist, wenn man sich auf solche abhängigen Mitglieder bezieht). Es scheint jedoch ein Problem zu geben, daher liste ich ein minimales Beispiel auf, das das Problem reproduziert.
Betrachten Sie den Code:
#include <iostream>
#include <bitset>
using namespace std;
template<class T>
struct B
{
T bitset{};
};
template<class T>
struct D : B<T>
{
bool foo()
{
return this->bitset < 32;
}
};
int main(){}
Die verwirrende Sache ist, dass, obwohl this->bitset
das Mitglied noch verwirrt B<T>::bitset
, der Compiler beziehen soll, ist und glaubt, dass wir auf std::bitset<std::size_t>
zu beziehen versuchen. Der Fehler tritt sowohl bei gcc6 als auch bei clang3.7 auf. Irgendwelche Ideen, warum das passiert? Qualifizieren Sie es mit B<T>::bitset
funktioniert aber.
Error (wörtlich):
In member function 'bool D<T>::foo(T, std::__cxx11::string)': cpp/scratch/minimal.cpp:24:22: error: invalid use of 'class std::bitset<1ul>'
EDIT
Das sieht für mich wie ein Parsing/Name-Lookup-Fehler. Wenn wir <
durch irgendeinen anderen Vergleichsoperator ersetzen (Danke @Leon für die Bemerkung), z.B.
return this->bitset == 32;
das Programm kompiliert. Also denke ich in this->bitset < 32
der Parser glaubt, dass wir versuchen, eine Vorlage zu instanziieren (<
Zeichen), und wir haben vergessen, die >
zu schließen. Habe aber auch keine Ahnung, ob das tatsächlich ein Bug ist oder wie die Sprache funktionieren soll.
Ich denke, der Compiler sagt Ihnen nur subtil, dass Sie wirklich std :: bitset;) anstelle einer repurposed Ganzzahl verwenden sollten. – rubenvb
Wahrscheinlich wegen der Art und Weise, wie 'name-lookup' funktioniert? 'name-lookup' in einem einfachen Fall überprüft den abgeleiteten Namespace und dann den Basis-Namespace und dann den globalen Bereich.Da "Base" hier abhängig ist, kann es nicht in seinen Gültigkeitsbereich schauen und es herausfinden, bis es eine Instanziierung findet. – Arunmu
@Arunmu: Ich erwarte, dass die Namenssuche bei Datenmembern und Elementfunktionen zurückgestellt wird. das scheint anders zu sein. –