2014-11-25 10 views
70

Mit C++ 11, Ubuntu 14.04, GCC Standard Toolchain.Ist es möglich, std :: string in einem conexpr zu verwenden?

Dieser Code schlägt fehl:

constexpr std::string constString = "constString"; 

error: the type ‘const string {aka const std::basic_string}’ of constexpr variable ‘constString’ is not literal... because... ‘std::basic_string’ has a non-trivial destructor

Ist es möglich, std::string in einem constexpr zu benutzen? (anscheinend nicht ...) Wenn ja, wie? Gibt es eine alternative Möglichkeit, eine Zeichenkette in einem constexpr zu verwenden?

+2

'std :: string' ist keine wörtliche Art –

+3

@PiotrS - die Frage sagt, dass ... – Vector

+0

@ Vektor nur literale Typen können "constexpr" gemacht werden. warum brauchst du 'std :: string' um constexpr zu sein? Vielleicht gibt es eine alternative Lösung –

Antwort

81

Nein, und Ihr Compiler gab Ihnen bereits eine umfassende Erklärung.

Aber Sie könnten dies tun:

constexpr char constString[] = "constString"; 

Zur Laufzeit kann diese verwendet werden, um eine std :: string zu konstruieren, wenn nötig.

+35

Warum nicht? Constexpr auto constString = "constString"; '? Keine Notwendigkeit, diese hässliche Array-Syntax zu verwenden ;-) – stefan

+16

Im Zusammenhang mit dieser Frage ist es klarer. Mein Punkt ist, über welche String-Typen Sie wählen können.'char []' ist ausführlicher/klarer als 'auto', wenn ich versuche, den zu verwendenden Datentyp hervorzuheben. – tenfour

+0

@stefan - Sicherlich bewertet es, was Zehnfach erklärt, aber das ist ein sehr cooler Weg, es zu tun. :) – Vector

13

Da das Problem der nicht-triviale Destruktor ist, ist es möglich, wenn der Destruktor aus std::string entfernt wird, eine constexpr Instanz dieses Typs zu definieren. Gefällt Ihnen dieses

struct constexpr_str { 
    char const* str; 
    std::size_t size; 

    // can only construct from a char[] literal 
    template <std::size_t N> 
    constexpr constexpr_str(char const (&s)[N]) 
     : str(s) 
     , size(N - 1) // not count the trailing nul 
    {} 
}; 

int main() 
{ 
    constexpr constexpr_str s("constString"); 

    // its .size is a constexpr 
    std::array<int, s.size> a; 
    return 0; 
} 
+2

Aber kein Standard-Bibliothekscode kennt Ihre Spezialklasse ... – einpoklum

+7

Das ist im Grunde was C++ 17 'string_view' ist, außer dass' string_view' Ihnen den größten Teil der Funktionalität gibt, die Sie von 'std :: string' kennen – wich

46

In C++ 17, können Sie string_view verwenden:

constexpr std::string_view sv = "hello, world";