2012-06-04 12 views
10

Nowy dosłowne pojęcie zdefiniowane przez użytkownika w języku C++ sugeruje kilka bardzo interesujących zastosowań String literały, takich jak:Czy literowe zdefiniowane przez użytkownika łańcuchy mogą być silnie wpisane?

"Goodbye %s world"_fmt("cruel"); 
"Goodbye %s world"_fmt(123); // Error: arg 1 must be convertible to const char* 

R"(point = \((\d+), (\d+)\))"_re; // Builds DFA at compile-time. 

typedef table< 
    column<"CustId"_name , std::string>, 
    column<"FirstName"_name, std::string>, 
    column<"LastName"_name , std::string>, 
    column<"DOB"_name  , date  > 
> Customer; 

Jednak, kiedy budować te rodzaje konstrukcji w gcc, np:

template <char... Chars> Name<Chars...> operator "" _name() { 
    return Name<Chars...>(); 
} 

auto a = 123_name; // OK 
auto b = "abc"_name; // Error 

pojawia się następujący błąd:

…unable to find string literal operator ‘operator"" _name’ with ‘const char [4]’, ‘long unsigned int’ arguments 

Od czytania wokół, zgaduję, że postać o zmiennej liczbie argumentów-szablon nie jest dostępna do UDLS czerpią d od literałów ciągowych.

  1. Czy w rzeczywistości literały łańcuchowe nie mogą zostać rozwiązane przy użyciu formularza szablonu variadic?
  2. Jeśli tak, to czy ktoś ma jakiś wgląd w to, dlaczego taka użyteczna forma UDL była poza standardem?
+0

Co dokładnie jest przydatne w tworzeniu nowego typu dla każdego dosłownego, rodzaju, który byłby całkowicie odrębny od siebie? –

+0

@NicolBolas: W pokazanych przykładach * chcesz * różne literały mieć różne typy. Co więcej, ostateczny typ literału niekoniecznie będzie naiwnym połączeniem jego postaci. Na przykład, "freq:% g Hz" świat "_fmt (44000)" może przekształcić się w coś podobnego do 'Formatter (" freq: "," Hz ") (44000)' za pomocą metaprogramowania –

+0

To by również oznaczało że * nie możesz * przekazać jej czegoś, co nie jest liczbą, więc nie możesz przekazać jej czegoś, co może użyć 'operator <<' do przekształcenia w strumień, co eliminuje możliwość dostosowywania typów danych. –

Odpowiedz

8

Masz rację. literały ciągów znaków nie może być używany z zmiennej liczbie argumentów formie szablonu (§2.14.8/5):

If L is a user-defined-string-literal, let str be the literal without its ud-suffix and let len be the number of code units in str (i.e., its length excluding the terminating null character). The literal L is treated as a call of the form

operator "" X (str, len) 

Mam przejrzał papiery wniosku (z których ostatni mogłem znaleźć był N2750) i nie mógł znaleźć wyjaśnienie za niedopuszczenie do użycia formularza szablonu variadic.

+0

Czy może to być coś tak banalnego jak jednoczesny rozwój dwóch funkcji, które uniemożliwiły korzystanie z drugiego? –

+0

@Matthieu M. Nie sądzę. Nie mogę znaleźć dowodów na to, że są rozwijane osobno (zawsze są razem w tym samym dokumencie). Szczerze mówiąc, kiedy zobaczyłem formularz variadic, pierwszą rzeczą, która przychodziła do głowy, było to, jakie idee OP prezentuje w odpowiedzi. Chciałbym założyć, że komisja dostrzegła potencjalny problem. Albo to albo bardzo irytujące niedopatrzenie. –

+3

Wszystkie zdefiniowane przez użytkownika literały, które umożliwiają korzystanie z formularza variadic, są ograniczone do podstawowego zestawu znaków źródłowych (po prostu dlatego, że gramatyka nie zezwala na nic innego w int lub float). Literały łańcuchowe nie mają tego ograniczenia, więc przy wielobajtowym kodowaniu źródłowym/wykonawczym masz litery c-liter w łańcuchu literowym, które mogą nie być reprezentowane jako pojedyncze znaki. To może mieć coś wspólnego z decyzją o nie dopuszczaniu formy variadic z literałami łańcuchowymi. – bames53

2

N3599, co na to pozwala, zostało zaimplementowane w gcc i clang.

template<class CharT, CharT... chars> 
int operator ""_suffix(){ 
    return 42; 
} 
Powiązane problemy