Ho scritto del codice per trasmettere const char*
a int
utilizzando constexpr
e quindi posso utilizzare un argomento const char*
come modello. Ecco il codice:Utilizzo di "constexpr" per utilizzare la stringa letterale per il parametro modello
#include <iostream>
class conststr
{
public:
template<std::size_t N>
constexpr conststr(const char(&STR)[N])
:string(STR), size(N-1)
{}
constexpr conststr(const char* STR, std::size_t N)
:string(STR), size(N)
{}
constexpr char operator[](std::size_t n)
{
return n < size ? string[n] : 0;
}
constexpr std::size_t get_size()
{
return size;
}
constexpr const char* get_string()
{
return string;
}
//This method is related with Fowler–Noll–Vo hash function
constexpr unsigned hash(int n=0, unsigned h=2166136261)
{
return n == size ? h : hash(n+1,(h * 16777619)^(string[n]));
}
private:
const char* string;
std::size_t size;
};
// output function that requires a compile-time constant, for testing
template<int N> struct OUT
{
OUT() { std::cout << N << '\n'; }
};
int constexpr operator "" _const(const char* str, size_t sz)
{
return conststr(str,sz).hash();
}
int main()
{
OUT<"A dummy string"_const> out;
OUT<"A very long template parameter as a const char*"_const> out2;
}
In questo codice di esempio, il tipo di out
è OUT<1494474505>
e tipo di out2
è OUT<106227495>
. La magia dietro questo codice è conststr::hash()
è una ricorsione constexpr
che utilizza FNV Hash function. E così crea un hash integrale per const char * che si spera sia un unico.
ho alcune domande su questo metodo:
- E 'questo un approccio sicuro da usare? O questo approccio può essere un male in un uso specifico?
- È possibile scrivere una funzione di hash migliore che crea un numero intero diverso per ogni stringa senza essere limitato a un numero di caratteri? (Nel mio metodo, la lunghezza è abbastanza lungo)
- Si può scrivere un codice che getta implicitamente
const char*
-int constexpr
viaconststr
e quindi non ci sarà bisogno esteticamente brutto (e anche il tempo dei consumatori)_const
stringa definita dall'utente letterale? Ad esempioOUT<"String">
sarà legale (e convertito "String" in intero).
Qualsiasi aiuto sarà apprezzato, grazie mille.
Se la mia risposta 'risolve' la tua domanda, può segnare come accettato? Altrimenti, puoi commentarlo (di nuovo)! – Synxis
Oh, le mie scuse, ho sempre dimenticato di farlo :) –