可变模板函数
Variadic template function
我试图在 C++ 中编写一个接受无限数量参数的函数。为此,我不得不在下面的函数中尝试它。
有两个参数:
unsigned int bitClear(uint32_t &bitNum, unsigned int pos)
{
bitNum = bitNum & (~(1 << pos));
return bitNum;
}
但是由于参数数量没有限制,我不想使用 STL 中的 cstdarg
。因为,在每次调用时,我必须给出函数使用的参数数量,然后是参数。
所以,我希望使用可变模板函数。我在这里和那里搜索解决方案,但我从 Stack Overflow 得到的答案并没有真正接近我正在寻找的东西。因此,通过查看第 4 章(可变参数模板)中的“C++ 模板完整指南”,我获得了一些有用的信息。
// base case
template<typename T>
decltype(auto) bitClear(T &t, unsigned int pos)
{
t = t & (~(1 << pos));
return t;
}
// general case
template<typename T1, typename T2, typename... Args>
decltype(auto) bitClear(T1 &t1, T2 pos2, Args... args)
{
t1 = t1 & ~((1 << pos2)|(1 << bitSet(args...))); // recursive call
return t1;
}
此方法使用递归调用来解压缩函数中的其余参数。不幸的是,我并没有把一切都做好。
#include <iostream>
#include <bitset>
#define MAX 16
using namespace std;
// the template functions are defined here
int main(int argc, char** argv)
{
unsigned int u = 0b11111111111111; // the same as 0xFFFF;
cout << "Clearing multiple bits at once : " << bitset<MAX>(bitClear(u, 2, 5)) << "\n";
cout << "Clearing multiple bits at once : " << bitset<MAX>(bitClear(u, 2, 5, 10)) << "\n";
cout << "Clearing multiple bits at once : " << bitset<MAX>(bitClear(u, 2, 5, 7, 10, 11)) << "\n";
return 0;
}
return :
Clearing multiple bits at once : 0011111111011011
Clearing multiple bits at once : 0011111111011011
Clearing multiple bits at once : 0011111111011011
这是不正确的,预期结果是:
Clearing multiple bits at once : 1111111111011011
Clearing multiple bits at once : 1111101111011011
Clearing multiple bits at once : 1111001101011011
将上述代码更改为:
///** Base case **///
template<typename T>
decltype(auto) bitClear(T &par1)
{
return par1;
}
///**General case **///
template<typename T1, typename... Args>
decltype(auto) bitClear(T1 t1, Args... args)
{
t1 = t1 & ~(1 << bitClear(args...));
return t1;
}
我无法得到想要的结果,我什至找不到我哪里出错了。有没有人有任何想法可以帮助我克服这个障碍?
大概是这样的:
template <typename Val, typename ... Pos>
Val& bitClear(Val& v, Pos... pos) {
((v &= ~(1 << pos)), ...);
return v;
}
我试图在 C++ 中编写一个接受无限数量参数的函数。为此,我不得不在下面的函数中尝试它。
有两个参数:
unsigned int bitClear(uint32_t &bitNum, unsigned int pos)
{
bitNum = bitNum & (~(1 << pos));
return bitNum;
}
但是由于参数数量没有限制,我不想使用 STL 中的 cstdarg
。因为,在每次调用时,我必须给出函数使用的参数数量,然后是参数。
所以,我希望使用可变模板函数。我在这里和那里搜索解决方案,但我从 Stack Overflow 得到的答案并没有真正接近我正在寻找的东西。因此,通过查看第 4 章(可变参数模板)中的“C++ 模板完整指南”,我获得了一些有用的信息。
// base case
template<typename T>
decltype(auto) bitClear(T &t, unsigned int pos)
{
t = t & (~(1 << pos));
return t;
}
// general case
template<typename T1, typename T2, typename... Args>
decltype(auto) bitClear(T1 &t1, T2 pos2, Args... args)
{
t1 = t1 & ~((1 << pos2)|(1 << bitSet(args...))); // recursive call
return t1;
}
此方法使用递归调用来解压缩函数中的其余参数。不幸的是,我并没有把一切都做好。
#include <iostream>
#include <bitset>
#define MAX 16
using namespace std;
// the template functions are defined here
int main(int argc, char** argv)
{
unsigned int u = 0b11111111111111; // the same as 0xFFFF;
cout << "Clearing multiple bits at once : " << bitset<MAX>(bitClear(u, 2, 5)) << "\n";
cout << "Clearing multiple bits at once : " << bitset<MAX>(bitClear(u, 2, 5, 10)) << "\n";
cout << "Clearing multiple bits at once : " << bitset<MAX>(bitClear(u, 2, 5, 7, 10, 11)) << "\n";
return 0;
}
return :
Clearing multiple bits at once : 0011111111011011
Clearing multiple bits at once : 0011111111011011
Clearing multiple bits at once : 0011111111011011
这是不正确的,预期结果是:
Clearing multiple bits at once : 1111111111011011
Clearing multiple bits at once : 1111101111011011
Clearing multiple bits at once : 1111001101011011
将上述代码更改为:
///** Base case **///
template<typename T>
decltype(auto) bitClear(T &par1)
{
return par1;
}
///**General case **///
template<typename T1, typename... Args>
decltype(auto) bitClear(T1 t1, Args... args)
{
t1 = t1 & ~(1 << bitClear(args...));
return t1;
}
我无法得到想要的结果,我什至找不到我哪里出错了。有没有人有任何想法可以帮助我克服这个障碍?
大概是这样的:
template <typename Val, typename ... Pos>
Val& bitClear(Val& v, Pos... pos) {
((v &= ~(1 << pos)), ...);
return v;
}