2016-03-20 7 views
0

ich den folgenden Code haben:const Qualifier auf Getter entfernt, wenn Template-Argument ist ein Zeiger

template <typename T> 
struct Val 
{ 
    T val; 

    const T& get() const { return val; } 
    void set(const T& newVal) { val = newVal; } 
}; 

int& f(const Val<int>& val) 
{ 
    return val.get(); 
} 

int* g(const Val<int*>& val) 
{ 
    return val.get(); 
} 

int main() 
{ 
    Val<int> val1; 
    f(val1); 

    Val<int*> val2; 
    g(val2); 

    return 0; 
} 

Es scheitert Kompilation in gcc mit der folgenden Meldung:

main.cpp: In function 'int& f(const Val<int>&)': 
main.cpp:78:20: error: invalid initialization of reference of type 'int&' from expression of type 'const int' 
    return val.get(); 
        ^
main.cpp:79:1: warning: control reaches end of non-void function [-Wreturn-type] 

, die völlig in Ordnung, aber warum ist nicht der gleiche Fehler für g() produziert? Warum wird das Qualifikationsmerkmal const aus irgendeinem Grund unter const T& entfernt, wenn T ein Zeiger ist?

Ich habe versucht, einige Ressourcen zu finden, aber es scheint schwer zu finden. Ich weiß, dass Meyers etwas in seinem neuesten Buch geschrieben hat, aber ich habe keinen Zugang dazu. Kann mir jemand auf Ressourcen oder Keywords verweisen, wo ich mehr über das ganze Thema des Vorlagentypabzugs finden könnte, wenn T ein Zeiger ist?

Antwort

0

Warum wird aus irgendeinem Grund die Konstante const auf const T & entfernt, wenn T ein Zeiger ist?

Da Sie den Zeiger nach Wert zurückgeben, nicht durch Referenz. Es ist völlig in Ordnung, einen Zeiger von einem const Zeiger initialisiert werden (beachten Sie, es ist die Zeiger, die const sind, nicht die Dinge, die sie zu zeigen.) Sie sind das Äquivalent dies zu tun:

int* const p0 = nullptr; // const pointer 
int* p1 = p0;   // copy to non-const is OK 

Wenn Sie waren zu initialisiere einen nicht kostenpflichtigen Verweis auf Poiter von einem Const-Zeiger, würde man einen ähnlichen Fehler wie im ersten Fall bekommen:

+0

Jetzt sehe ich natürlich. In 'const T &' schützt das 'const' das ganze' T', nicht den Wert innerhalb. – bobbel

+0

@bobbel Ich weiß nicht wirklich, was du damit meinst. – juanchopanza

+0

Sorry, ja verwirrend. Nicht wichtig. Entdeckt einen Fehler in meinem Denken. Ich erwartete 'Val ' und 'Val ' das gleiche Verhalten auf dem inneren 'int' zu haben. – bobbel