使用可变模板的编译时'字符串'操作 [英] Compile-time 'String' Manipulation with Variadic Templates

查看:131
本文介绍了使用可变模板的编译时'字符串'操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嘿,所有,我目前正试图编写一个编译时字符串加密(使用'字符串'和'加密'相当宽松)lib。



我到目前为止如下:

  // Cacluate在编译时的窄字符串长度
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;
};

//'在编译时加密窄字符串
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;
//打印DEF
}

注意 CountArgs 是多余的(这就是 sizeof ... ),并且这使用元素方式转换参数包中的元素






要使转换依赖于前面的结果,一个选项是递归地使用字符,一次一个,逐步构建新模板:

 模板< char ... P> struct StringBuilder {
template< char C> struct add_char {
typedef StringBuilder< P ...,C>类型;
};

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; //或任何
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;
};


Hey all, I'm currently trying to write a compile-time string encryption (using the words 'string' and 'encryption' quite loosely) lib.

What I have so far is as follows:

// 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...
};

However I can't figure out how to perform operations on the characters as I expand them into the static array. I'd just like to execute a simple operation on each character (e.g. '(((c ^ 0x12) ^ 0x55) + 1)' where c is the character).

A shove in the right direction would be greatly appreciated.

Thanks all.

解决方案

If you just want to operate on one character at a time its easy:

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"
}

Note that CountArgs is redundant (that's what sizeof... is for) and that this uses element-wise transformation of the elements in a parameter-pack.


To make the transformation dependent on previous results, one option would be to consume the characters recursively, one at a time, and incrementally build a new template from that:

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;
};

这篇关于使用可变模板的编译时'字符串'操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆