Verwenden von "constexpr", um Zeichenfolgenliteral für Vorlagenparameter zu verwenden
Ich geschrieben habe etwas code zu werfen const char*
zu int
mithilfe constexpr
und somit kann ich mit einem const char*
als ein template-argument. Hier ist der code:
#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 diesem Beispiel-code, die Art der out
ist OUT<1494474505>
und Art der out2
ist OUT<106227495>
. Magie, die hinter diesem code ist conststr::hash()
es ist ein constexpr
Rekursion verwendet FNV Hash-Funktion. Und so schafft es ein integraler hash für const char*, die hoffentlich eine einmalige.
Ich habe einige Fragen zu dieser Methode:
- Ist dies eine sichere Ansatz zu verwenden? Oder kann dieser Ansatz sein, eine böse, die in eine bestimmte Verwendung?
- Können Sie schreiben, eine bessere hash-Funktion, erzeugt verschiedene ganze Zahl für jede saite), ohne Beschränkung auf eine Anzahl von chars? (bei meiner Methode, der ist lang genug)
- Können Sie schreiben einen code, der implizit CASTET
const char*
zuint constexpr
überconststr
so dass wir nicht brauchen, ästhetisch hässliche (und auch die Zeit, Verbraucher)_const
Benutzer-definierten string-literal? Zum BeispielOUT<"String">
legal (und cast "String" , integer).
Jede Hilfe wird sehr geschätzt, thanks a lot.
Kommentar zu dem Problem
Wenn meine Antwort 'löst' Ihr die Frage, markieren Sie es als angenommen ? Andernfalls können Sie kommentieren es (wieder)!
Oh, ich bitte um Entschuldigung, ich vergesse immer zu tun 🙂
InformationsquelleAutor der Frage Equalities of polynomials | 2013-04-07
Du musst angemeldet sein, um einen Kommentar abzugeben.
Obwohl deine Methode ist sehr interessant, es ist nicht wirklich ein Weg, um pass ein literaler string als ein template-argument. In der Tat, es ist ein generator von template-argument basiert auf string-literal, das ist nicht das gleiche: Sie können nicht abrufen
string
aushashed_string
... Es irgendwie Niederlagen der ganze Interesse von string-literalen in Vorlagen.BEARBEITEN : das folgende war Recht, wenn der hash verwendet wurde, war die gewichtete Summe der Buchstaben, das ist nicht der Fall nach dem Bearbeiten der OP.
Soweit ich weiß, Sie können nicht übergeben Sie einen string-literal in einem template-argument einfach in den aktuellen standard. Sie können jedoch "fake". Hier ist, was ich verwenden im Allgemeinen:
Dann verbringe ich die "fake-string-literal" über eine Art argument:
EDIT2: Sie sagte in den Kommentaren, die Sie verwendet, dies zu unterscheiden zwischen mehreren Spezialisierungen einer Klasse Vorlage. Die Methode, die Sie gezeigt haben, ist gültig, aber Sie können auch verwenden tags:
InformationsquelleAutor der Antwort Synxis
Hier ist das Muster, dass ich für das template const-string-Parameter.
class F {
static constexpr const char conststr[]= "some const string";
TemplateObject<conststr> instance;
};
finden Sie unter :
https://stackoverflow.com/a/18031951/782168
InformationsquelleAutor der Antwort h4ck3rm1k3