2014-07-25 18 views
5

Eksperymentuję z niestandardowymi literałami C++. Dziwne jest to, że poniższa funkcja prosta przestaje działać, gdy zmienię typ z long double na double, lub gdy spróbuję przejść przez odniesienie.Niestandardowa literalna działa z długimi podwójnymi, ale nie podwójnymi wartościami, z przekazaniem wartości, ale nie przechodząc przez odniesienie

Na początku myślałem, że miał do czynienia z wykorzystaniem constexpr ale które nie wydają się być w przypadku, gdy oba te działają dobrze, jeśli nie jest na operator "" i usuwanie constexpr z operator "" nie usuwa błąd.

Czy są to przemyślane decyzje przy projektowaniu języka, czy tylko niuanse, których mój kompilator (gcc 4.8.2) nie jest w stanie rozwiązać?

// Conversion function, works fine with both long double and 
// double, and with or without pass by reference. 
constexpr long double to_deg (const long double& deg) 
{ 
    return deg*M_PI/180.0; 
} 

// Custom literal with long double types and pass by value, 
// works fine. 
constexpr long double operator "" _deg (long double deg) 
{ 
    return deg*M_PI/180.0; 
} 

// Custom literal with double types, gives "Invalid argument list." 
// error. 
constexpr double operator "" _deg (double deg) 
{ 
    return deg*M_PI/180.0; 
} 

// Custom literal with pass by reference, gives "Invalid argument list." 
// error. Removing the const does not remove the error. 
constexpr long double operator "" _deg (const long double& deg) 
{ 
    return deg*M_PI/180.0; 
} 
+2

Ponieważ język mówi, że "double" jako parametr jest niepoprawny, a odniesienia również nie są. Nie jestem pewien, dlaczego naprawdę tego potrzebujesz. – chris

+0

@chris Nie chodzi o to, że naprawdę muszę to zmienić, po prostu eksperymentuję :). OK, znalazłem specyfikację "tylko długi podwójny", ale nie mogę znaleźć nic na temat żadnych odniesień. – MGA

+2

Standard zawiera listę prawidłowych wyborów. Referencje tam nie są. Aby uzyskać bardziej zwięzłą wersję, możesz wypróbować [odniesienie] (http://en.cppreference.com/w/cpp/language/user_literal). – chris

Odpowiedz

5

C++ Standard, sekcja § 13.5.8 (literały zdefiniowane przez użytkownika), wymienia wszystkie poprawne typy:

Deklaracja operatora dosłownym będą mieć parametr deklaracja klauzula równoznaczne z jednego z następujących:

  • char *
  • unsigned long długo Int
  • long double
  • char
  • wchar_t
  • char16_t
  • char32_t
  • const char * std :: size_t
  • const wchar_t *, std :: size_t
  • const char16_t * std: : size_t
  • const char32_t *, std :: size_t

Ani double ani double&, const long double& nie są tutaj wymienione: więc nie są dozwolone.

+1

Lista parametrów 'const long double' jest odpowiednikiem listy parametrów' long double'. – chris

+0

ofc, dzięki za uwagę, edytowane. – quantdev

+0

Z jakiegokolwiek powodu podwójne jest wykluczone? – ar2015