嘿所有,我现在正在尝试编写一个编译时字符串加密(使用“string”和“加密”这两个词)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是字符)。
非常感谢正确方向的推动。
谢谢大家。
答案 0 :(得分:4)
如果您只想一次操作一个角色,那么很容易:
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...
的用途)并且使用element-wise transformation of the elements in a 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;
};
答案 1 :(得分:1)
如果我理解你想要正确做什么(实际上在编译时创建一个数组)我认为可变参数模板是不够的,你将不得不等待constexpr
。
但是,如果你不需要一个实际的数组而且可以使用类似于tuple
get<I>
的东西而妥协,那么它就可以了(你可以在那里构建一个char
数组运行)。