2009-09-24 17 views
24

Po przeczytaniu oświadczenia wiele razy w artykułach - chcę dodać to pytanie do Stackoverflow i zapytać społeczność - czy poniższy kod jest przenośny?Kontener biblioteki standardowej z dodatkowymi opcjonalnymi parametrami szablonu?

template<template<typename T, typename Alloc> class C> 
void f() { 
    /* some code goes here ... */ 
} 

int main() { 
    f<std::vector>(); 
} 

jest realizacja, która dostarcza std::vector naprawdę może mieć dodatkowe, niespłaconych parametrów szablonu poza dwoma znanymi z nich? Powoduje to, że powyższy kod jest źle sformułowany, ponieważ przyjmuje dwa parametry szablonu. Ostatni przykład in this article zawiera przykład takiego roszczenia.

Odpowiedz

22

znalazłem następujący issue report, który mówi

Nie ma dwuznaczności; standard jest jasny, jak napisano. Implementatorzy bibliotek nie mogą dodawać parametrów szablonów do standardowych klas bibliotek. Nie podlega to zasadzie "jak gdyby", więc byłoby to dozwolone tylko wtedy, gdyby standard dawał wyraźną licencję dla implementatorów, aby to zrobić. Wymagałoby to zmiany w standardzie.

Firma LWG postanowiła nie wprowadzać tej zmiany, ponieważ złamałaby kod użytkownika związany z szablonami parametrów szablonów lub specjalizacjami standardowych szablonów klas biblioteki.

Książki i osoby, które mówią, że implementacja może dodać inne opcjonalne parametry, wydają się błędne.

1

Sprawdź subskrypcje 17.4.4 [lib.conforming].

17.4.4.3/3 mówi, że "funkcja globalna lub nie-członkowska nie może zostać zadeklarowana przez implementację jako przyjmująca dodatkowe domyślne argumenty", ale 17.4.4.4/2 wyraźnie pozwala na zamianę podpisów funkcji członków o dłuższych tak długo ponieważ dodatkowe parametry mają wartości domyślne.

Nie ma jednak żadnej sekcji szablonów, więc jeśli poczuli potrzebę dostarczenia 17.4.4.3/3, wydaje mi się, że dodatkowe parametry szablonu są dopuszczalne, jeśli nie podano inaczej.

+0

Ok, nieważne - sprawozdanie kwestią jest oczywiście lepiej niż zgaduję: P – me22

0

Też widziałem to roszczenie. Ale.

Po pierwsze, nigdy nie widziałem realizacji tego. Wydaje mi się, że pamiętam, że Andrei Alexandrescu zastanawiał się kiedyś nad użyciem takich rzeczy jak typy przydzielające na sterydach (coś w rodzaju my_fancy_thing<std::allocator,more_info_to_pass_to_the_container>, podczas gdy tylko std::allocator nadal będzie działać). Ale nawet to sprawiłoby, że twoja maszyna działała, a to jest najbardziej zbliżone do implementacji, która przełamuje twój przykład, o którym kiedykolwiek słyszałem.

Wydaje mi się, że jest to prawie ta sama kategoria co twierdzenie, że wskaźnik 0 niekoniecznie musi być reprezentowany przez wartość ze wszystkimi bitami ustawionymi na zero - nawet jeśli sprzedawcy naprawdę mają tę wolność (co ja t wie, skoro są roszczenia z obu stron), nigdy ich nie użyją, ponieważ złamie to zasadniczo cały istniejący kod.

Więc już dawno postanowiłem nie przejmować się tym.

+0

Ktoś zgłosił problem i prośbę o pobranie dla [ładnej drukarki] (http://louisdx.github.com/cxx-prettyprint/) jeden raz pod pozorem, że te dodatkowe argumenty rzeczywiście pojawiły się w ich kodzie MSVC iw ten sposób sprawił, że dostarczone przeze mnie specjalizacje przełamały ... :-( –

2

Niewiarygodnie, byłem niedawno przeczytaniu „C++ szablony: The Complete Guide” i ostatnia książka zaznaczone następujące na stronie 111:

Szablon szablon argument musi być szablon klasy z parametrów, które dokładnie dopasować parametry parametr szablonu szablonu zastępuje.Domyślne argumenty szablonu argumentu szablonu szablonu są ignorowane (ale jeśli parametr szablonu szablonu ma domyślne argumenty, są one uwzględniane podczas tworzenia szablonu).

Tak więc, jeśli książka ma być przekonana, twój przykład, w którym niestandardowe parametry domyślne są dodawane do std :: vector, byłby legalny - ponieważ domyślne argumenty szablonu szablonu szablonu są ignorowane.

Jako test świata rzeczywistego, Skompilowałem następujących w g ++ (z powodzeniem) i Visual Studio 2008 (nie udało się na niedopasowane parametrów):

template<typename T1, typename T2, typename T3 = float> 
class MyClass 
{ 
public: 
    T1 v1; 
    T2 v2; 
    T3 v3; 
}; 

template<template<typename T1, typename T2> class C> 
void f() 
{ 
    C<int,double> *c = new C<int,double>(); 
} 

int main() 
{ 
    f<MyClass>(); 
    return 0; 
} 
+2

Co mają na myśli, gdy "Domyślne argumenty szablonu szablonu szablonu są ignorowane" to to, że chociaż parametr może mieć domyślny argument, ten domyślny argument to nie ty sed i odpowiedni parametr zlicza tak, jakby nie miał domyślnego argumentu. Jeśli więc imp miałby wektor z 3 parametrami, a trzeci miałby domyślny argument, to przekazywanie wektora jako argumentu szablonu szablonu jest takie, jak gdyby tego domyślnego argumentu nie było. –

+0

Próbowałem skompilować przykład za pomocą g ++ 4.4.1 - odrzuca, a g ++ 4.1 akceptuje kod. Wygląda na to, że był to błąd w GCC. –

+0

Dzięki za wyjaśnienie tego fragmentu - interpretowałem to nieco inaczej. Skompilowałem 4.1 (starsza maszyna wirtualna Fedory, którą kopałem). – csj

Powiązane problemy