2016-03-20 7 views
2

ich die folgenden 3 C++ Dateien (das Problem tritt nicht auf, wenn alle in 1 Datei) sind:Warum wird in der constexpr-Funktion ein Verweis auf const-Zeiger zurückgegeben, aber keine Kopie zurückgegeben?

clazz.hpp:

class Clazz { 
    public: 
     static const char* const NAME; 
}; 

clazz.cpp:

#include "clazz.hpp" 
const char* const Clazz::NAME = "Clazz"; 

Haupt .cpp:

#include <iostream> 
#include "clazz.hpp" 

constexpr const char* const& get_clazz_name_ref() { 
    return Clazz::NAME; 
} 

constexpr const char* get_clazz_name() { 
    return Clazz::NAME; // this does not work 
} 

int main(void) { 
    std::cout << get_clazz_name_ref() << std::endl; 
    std::cout << get_clazz_name() << std::endl; 
} 

Beim Kompilieren dieser Dateien in Visual Studio 2015, erhalte ich einen Fehler m Nachricht für die get_clazz_name Funktion:

error C3256: 'NAME': variable use does not produce a constant expression 

Komischerweise wird die Funktion get_clazz_name_ref OK zusammengestellt. Warum ist das so?


Als Reaktion auf Alan Stokes https://stackoverflow.com/a/36112146/59557: Warum ist dieser Arbeits?

clazz.hpp:

#include <array> 
class Clazz { 
    public: 
     static const char* const NAME; 
     static const size_t N = 3; 
     static const std::array<const char*, N> NAMES; 
}; 

clazz.cpp:

#include "clazz.hpp" 
const char* const Clazz::NAME = "Clazz"; 

const std::array<const char*, Clazz::N> Clazz::NAMES = { 
    "A", 
    "B", 
    "C" 
}; 

main.cpp:

#include <iostream> 
#include "clazz.hpp" 

constexpr const char* const& get_clazz_name_ref() { 
    return Clazz::NAME; 
} 

constexpr const char* get_name(size_t i) { 
    return Clazz::NAMES[i]; 
} 

int main(void) { 
    std::cout << get_clazz_name_ref() << std::endl; 
    std::cout << get_name(0) << std::endl; 
} 

Ich konnte clazz.cpp ändern und wieder aufzubauen, zu.

+0

Ihr Code kompiliert nicht, wenn ich alles in der gleichen Datei ablege. – Holt

+0

Hmm, ich dachte es kompiliert für mich. Vielleicht habe ich eine Fehlermeldung verpasst. –

+0

Welchen Compiler benutzen Sie? Vielleicht könnten Sie den vollständigen Code posten, der kompiliert wird? – Holt

Antwort

4

Die Adresse NAME ist dem Compiler beim Kompilieren main.cpp bekannt, aber sein Wert ist nicht. Daher kann der Wert keine Kompilierzeitkonstante sein.

(Man könnte clazz.cpp nur ändern und wieder aufzubauen, ihm zu geben, einen anderen Wert, so kann es nicht konstant sein.)

Das gilt nicht, wenn sie in einer Datei sind, weil dann der initialiser ist sichtbar und der Wert ist bekannt.

+0

Ich bekomme Ihre Erklärung, aber wie kommt es, wenn 'const char *' Werte aus einem 'std :: array' Mitglied von' Clazz', definiert in 'clazz.cpp', zu 'constexpr' (siehe aktualisierte Frage) gemacht werden kann . –