2012-11-09 14 views
6
template<typename T> 
void print_size(const T& x) 
{ 
    std::cout << sizeof(x) << '\n'; 
} 

int main() 
{ 
    print_size("If you timidly approach C++ as just a better C or as an object-oriented language, you are going to miss the point."); 
    // prints 115 
} 

To drukuje 115 na najnowszym kompilatorze g ++. Najwyraźniej, T jest wydedukowana jako tablica (zamiast wskaźnika). Czy to zachowanie gwarantuje standard? Byłem trochę zaskoczony, ponieważ poniższy kod wypisuje rozmiar wskaźnika i myślałem, że auto zachowuje się dokładnie tak samo jak odliczanie argumentów w szablonie?Odliczanie argumentów szablonowych dla literałów łańcuchowych

int main() 
{ 
    auto x = "If you timidly approach C++ as just a better C or as an object-oriented language, you are going to miss the point."; 
    print_size(x); 
    // prints 4 
} 
+1

Nie teraz dla pierwszego, ale drugi nie jest nieoczekiwany. Literały łańcuchowe SĄ tablicami, prawda? – Tomek

+2

Dla każdego, kto czyta to, kto nie wie: nie możesz przekazać tablic według wartości (rozpadają się na wskaźniki), ale na pewno możesz przekazać odwołanie do tablicy. W tym przypadku 'const T &' staje się odwołaniem do tablicy, więc 'sizeof' daje rozmiar tablicy. –

+1

Odpowiedź Martinho obejmuje główne pytanie. Dla zachowania jest zagwarantowane, 14.8.2.1/2: "Jeśli' P' nie jest typem odniesienia: Jeśli 'A' jest typem tablicy, typ wskaźnika wytworzony przez konwersję standardową tablica-do-wskaźnika jest używany zamiast 'A' dla dedukcji typu; ..." gdzie 'P' jest typem parametru funkcyjnego funkcji szablonu, który może obejmować jeden lub więcej parametrów szablonu, a' A' jest typem wyrażenia używanego w wywołaniu funkcji. – aschepler

Odpowiedz

8

auto zachowuje się dokładnie jak odliczenia szablon argumentów. Dokładnie jak T!

Porównaj to:

template<typename T> 
void print_size(T x) 
{ 
    std::cout << sizeof(x) << '\n'; 
} 

int main() 
{ 
    print_size("If you timidly approach C++ as just a better C or as an object-oriented language, you are going to miss the point."); 
    // prints 4 
    auto x = "If you timidly approach C++ as just a better C or as an object-oriented language, you are going to miss the point."; 
    print_size(x); 
    // prints 4 
} 

z tym:

template<typename T> 
void print_size(const T& x) 
{ 
    std::cout << sizeof(x) << '\n'; 
} 

int main() 
{ 
    print_size("If you timidly approach C++ as just a better C or as an object-oriented language, you are going to miss the point."); 
    // prints 115 
    const auto& x = "If you timidly approach C++ as just a better C or as an object-oriented language, you are going to miss the point."; 
    print_size(x); 
    // prints 115 
} 

Niezupełnie, ale to nie jest jeden z przypadków narożnych.

+0

Głupi mnie. Dziękuję za podniesienie kurtyny :) – fredoverflow

+0

Ponieważ, oczywiście, nie można przekazać tablicy w stylu C jako wartości w C++. – Yakk

+0

@Yakk: Rzeczywiście, ponieważ złamałoby to kompatybilność z C. C nie miał referencji, więc nie istniało żadne zachowanie, które mogłoby się tam złamać. – MSalters

Powiązane problemy