[英]Compile-time 'String' Manipulation with Variadic Templates
大家好,我目前正在嘗試編寫一個編譯時字符串加密(非常寬松地使用單詞“ string”和“ encryption”)lib。
到目前為止,我所擁有的如下:
// Cacluate narrow string length at compile-time
template <char... ArgsT>
struct CountArgs
{
template <char... ArgsInnerT> struct Counter;
template <char Cur, char... Tail>
struct Counter<Cur, Tail...>
{
static unsigned long const Value = Counter<Tail...>::Value + 1;
};
template <char Cur>
struct Counter<Cur>
{
static unsigned long const Value = 1;
};
static unsigned long const Value = Counter<ArgsT...>::Value;
};
// 'Encrypt' narrow string at compile-time
template <char... Chars>
struct EncryptCharsA
{
static const char Value[CountArgs<Chars...>::Value + 1];
};
template<char... Chars>
char const EncryptCharsA<Chars...>::Value[CountArgs<Chars...>::Value + 1] =
{
Chars...
};
但是,當我將字符擴展到靜態數組中時,我無法弄清楚如何對字符執行操作。 我只想對每個字符執行一個簡單的操作(例如'((((c ^ 0x12)^ 0x55)+ 1)'其中c是字符)。
朝正確的方向前進將不勝感激。
謝謝大家
如果只想一次操作一個字符,這很簡單:
template<char c> struct add_three {
enum { value = c+3 };
};
template <char... Chars> struct EncryptCharsA {
static const char value[sizeof...(Chars) + 1];
};
template<char... Chars>
char const EncryptCharsA<Chars...>::value[sizeof...(Chars) + 1] = {
add_three<Chars>::value...
};
int main() {
std::cout << EncryptCharsA<'A','B','C'>::value << std::endl;
// prints "DEF"
}
請注意, CountArgs
是多余的(那是sizeof...
目的),並且它使用parameter-pack中元素的逐元素轉換 。
為了使轉換依賴於先前的結果,一種選擇是遞歸使用字符,一次使用一個,然后從中逐步構建一個新模板:
template<char... P> struct StringBuilder {
template<char C> struct add_char {
typedef StringBuilder<P..., C> type;
};
static const char value[sizeof...(P)+1];
};
template<char... P> const char StringBuilder<P...>::value[sizeof...(P)+1] = {
P...
};
template<class B, char...> struct EncryptImpl;
template<class B, char Seed, char Head, char... Tail>
struct EncryptImpl<B, Seed, Head, Tail...> {
static const char next = Head + Seed; // or whatever
typedef typename EncryptImpl<
typename B::template add_char<next>::type,
next, Tail...
>::type type;
};
template<class B, char Seed> struct EncryptImpl<B, Seed> {
typedef B type;
};
template<char... P> struct Encrypt {
typedef typename EncryptImpl<StringBuilder<>, 0, P...>::type type;
};
如果我了解您要正確執行的操作(實際上是在編譯時創建一個數組),我認為可變參數模板還不夠,您必須等待constexpr
。
但是,如果您不需要實際的數組,而是可以折衷使用類似於tuple
的get<I>
則有可能(然后可以在運行時構建char
數組)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.