2014-09-18 36 views
6

W this comment to another question The HVD użytkownik stwierdził, co następuje:Czy tablice mogą być indeksowane podczas kompilacji?

... chociaż literały łańcuchowe mogą być przekazywane do constexpr funkcji, i indeksowania tablicy jest dozwolone na napisowych w stałym wyrażeń operacji indeksowania na zasadzie constexpr parametr funkcji nie kwalifikuje się jako wyrażenie stałe.

Nie do końca rozumiem, o co chodziło. Czy to znaczy, że zmienna w następującym kodzie hash_value

#include <cstddef> 

// Compute the hash of a string literal adding the values of its characters 
template<std::size_t N> constexpr std::size_t 
hash_string 
    (const char (& s)[N]) 
noexcept 
{ 
    std::size_t h = 0; 

    // Array indexing happening under the hood 
    for (const auto c : s) 
     h += c; 

    return h; 
} 

constexpr auto hash_value = hash_string("Hello, world!"); 

nie może być oceniana w czasie kompilacji? Czy mógłbyś rozwinąć cytowany komentarz i powiedzieć, czy mam rację?

+0

Nie widzę niczego w standardzie C++ 14, który zabrania tego. Twój kod świetnie się komplikuje. –

+0

Czy wiele kompilatorów tworzy taką optymalizację? To wydaje się bardzo agresywne. – tadman

+0

@ T.C. Tak, kompiluje się i działa dobrze dla mnie też na Clangu. Jednak szczególnie, ponieważ nie znam zespołu, chcę się upewnić, że jest on oceniany podczas kompilacji. – Kalrish

Odpowiedz

3

co mówię w tym komentarzu, że nie można mieć coś podobnego

template <int N> 
int f(); 

constexpr int g(int i) { 
    return f<i>(); // invalid 
} 

bo chociaż wynikiem constexpr funkcji może być stałym wyrażeniem, wewnątrz organizmu, jego parametry nie są. Funkcja constexpr może być wywołana ze stałą lub z niestanowiącymi stałych argumentów, wywołujący decyduje, a C++ nie ma żadnej funkcji, która może być wywołana ze stałymi argumentami.

To miało znaczenie w odpowiedzi, którą czytałeś, ponieważ przydatne byłoby mieć argument funkcji const char (&str)[N] i traktować str[i] jako wyrażenie stałe w treści funkcji.

To nie ma znaczenia dla kodu, który masz. Ten kod jest w porządku.

+0

Dziękujemy! Teraz to rozumiem: funkcja 'constexpr' ma wartość _enabled_ do oceny w czasie kompilacji, ale nie jest wymagana. Dlatego może być użyty w kontekście, w którym wymagane są wyrażenia stałe, ale nie można założyć, że zawsze będzie działał w czasie kompilacji. Dlatego argumenty funkcji "constexpr' nie mogą być analizowane w' static_assert'. – Kalrish

+0

+1 (od wczoraj) dziękuję za monitorowanie i wyjaśnianie. –

2

przeszedłem odpowiednich sekcjach zarówno N3337 i N3936, i nic w obu wersji standardu zakazuje constexpr funkcję sortowania

template<std::size_t N> constexpr std::size_t 
hash_string 
    (const char (& s)[N]) 
noexcept 
{ 
    return s[0]; 
} 

A w rzeczywistości to kompiluje w obu g ++ i brzękiem w C++ tryb 11. Nie mam absolutnie żadnego pojęcia, skąd się wzięło twierdzenie, że "operacja indeksowania na parametrze funkcji constexpr nie kwalifikuje się jako wyrażenie stałe". Nie mogę znaleźć niczego w §5.19 [expr.const], który zabrania tego.

+0

Czy problem może wynikać z użycia pętli 'for'? –

+0

@RSahu To jest problem C++ 14 vs. C++ 11. Pętla nie jest dozwolona w C++ 11 'constexpr', ale roszczenie indeksujące nie ma związku z tym. –

+0

@hvd Wciąż chciałbym poznać powody cytowanego oświadczenia, nawet po twoim standardowym wyjaśnieniu. Intryguje mnie :). – Kalrish

Powiązane problemy