2012-05-02 17 views
5

Czy istnieje sposób na wdrożenie ciągów do pracy zarówno w czasie kompilacji, jak i czasu wykonywania?C++ 11 implementacja ciągów constexpr

AFAIK dla klasy, która ma być skonstruowana przez constexpr, musi mieć trywialny destruktor. Jednak okazuje się to trudne, gdy mamy do czynienia z łańcuchami. Jeśli ciąg NIE jest constexpr, to musi zwolnić pamięć. Jednak jeśli jest to IS constexpr, to jest statycznie przydzielane i nie powinno być usuwane, umożliwiając w ten sposób trywialny destruktor.

Nie można jednak powiedzieć "Hej, Kompilatorze! Jeśli jestem constexpr, nie musisz mnie niszczyć!" Albo to jest?

To byłoby coś jak poniżej:

class string { 
private: 
    char * str; 
public: 
    template<std::size_t l> 
    constexpr string(const char (&s)[l]) : str(&(s[0])) {} 
    string(const char * s) { str = strdup(s); } 
    static if (object_is_constexpr) { 
     ~string() = default; 
    } 
    else { 
     ~string() { free(str); } 
    } 
}; 

Najbliżej byłem w stanie przyjść jest posiadanie dwóch odrębnych typów, łańcuch i constexpr_string, zdefiniowana przez użytkownika dosłowne _string powracającego constexpr_string, a użytkownik -definiowana niejawna konwersja z constexpr_string na string.

To niezbyt miłe, ponieważ const auto s = "asdf"_string; działa, ale nie działa pod . Dodatkowo referencja/wskaźnik do constexpr_string nie będzie konwertować. Dziedziczenie w obu kierunkach powoduje nieintuicyjną "gotcha" i nie rozwiązuje pierwszego problemu.

Wygląda na to, że powinno być możliwe, o ile kompilator miałby ZAUFAĆ programistce, że constexpr nie musiał być niszczony.

Jeśli mam nieporozumienie, daj mi znać.

+0

Myślę, że szukasz 'strwrap' z http://akrzemi1.wordpress.com/2011/05/11/parsing-strings-at-compile-time-part-i/ – Cubbi

+0

Literały ciągów znaków' const char (& Var) [N] '_to_ typ łańcucha' constexpr'. –

+1

Musisz pokochać, gdy ludzie zaczną używać funkcji takich jak 'static if', zanim zostaną zatwierdzeni! –

Odpowiedz

9

To nie tylko kwestia zniszczenia.

Operacja constexpr powinien wywołać tylko inne constexpr operacje i new, malloc itp ... są nieconstexpr. Zauważ, że jest to właściwość sprawdzona statycznie i nie zależy od argumentu środowiska wykonawczego, więc wywołanie takiej funkcji musi być całkowicie nieobecne, a nie tylko ukryte w gałęzi, która (rzekomo) nie jest zajęta.

Jako takie, nigdy nie będzie możliwe uzyskanie constexprstring.

+0

Nie może to być nawet konstruktor inny niż constexpr?Wydaje się, że powinno być możliwe posiadanie konstruktorów constexpr i non-constexpr dla danego typu, tak jak możliwe jest posiadanie metod const i non const. –

+0

Możesz całkowicie utworzyć ciąg 'constexpr', po prostu nie będzie on w stanie obsłużyć łańcuchów innych niż constexpr. Po prostu wykonaj funkcje konwersji. –

+0

Sposób, w jaki to widzę, to constexpr to sposób na rozmycie linii między czasem kompilacji a czasem działania. Typy pierwotne pozwalają na to i wydaje się, że powinno być możliwe wykonanie pewnych czynności, aby wskaźniki w klasach wskazywały literalną lub dynamicznie przydzielaną pamięć. Języki funkcjonalne są od teraz pobierane przez granicę czasu kompilacji/czasu pracy. @Mooing Duck: funkcje konwersji wydają się łamać abstrakcję –

0

Jest możliwe, do pewnego stopnia, zobacz the code example in this page. Można tworzyć obiekty constexpr conststr i wywoływać na nich niektóre operacje, ale nie można ich używać jako parametrów szablonu non-type.

Powiązane problemy