如何将变换的integer_sequence
(或类似的,因为我将C ++ 11作为目标)插入到可变参数模板参数中?
例如,我有一个表示一组逐位标志的类(如下所示)。它是使用嵌套类生成的,因为同一个类不能有两个可变参数模板参数。它将像typedef Flags<unsigned char, FLAG_A, FLAG_B, FLAG_C>::WithValues<0x01, 0x02, 0x04> MyFlags
一样使用。通常,它们将与2的幂一起使用(尽管并非总是如此,在某些情况下会进行某些组合,例如,可以想象一组标志,如Read = 0x1,Write = 0x2和ReadWrite = 0x3为0x1 = | 0X2)。我想提供一种方法typedef Flags<unsigned char, FLAG_A, FLAG_B, FLAG_C>::WithDefaultValues MyFlags
。
template<class _B, template <class,class,_B> class... _Fs>
class Flags
{
public:
template<_B... _Vs>
class WithValues :
public _Fs<_B, Flags<_B,_Fs...>::WithValues<_Vs...>, _Vs>...
{
// ...
};
};
我尝试了以下但没有成功(放在Flags类中,在WithValues类之外):
private:
struct _F {
// dummy class which can be given to a flag-name template
template <_B _V> inline constexpr
explicit _F(std::integral_constant<_B, _V>) { } };
// we count the flags, but only in a dummy way
static constexpr unsigned _count = sizeof...(_Fs<_B, _F, 1>);
static inline constexpr
_B pow2(unsigned exp, _B base = 2, _B result = 1) {
return exp < 1 ?
result :
pow2(exp/2,
base*base,
(exp % 2) ? result*base : result);
}
template <_B... _Is> struct indices {
using next = indices<_Is..., sizeof...(_Is)>;
using WithPow2Values = WithValues<pow2(_Is)...>;
};
template <unsigned N> struct build_indices {
using type = typename build_indices<N-1>::type::next;
};
template <> struct build_indices<0> {
using type = indices<>;
};
//// Another attempt
//template < _B... _Is> struct indices {
// using WithPow2Values = WithValues<pow2(_Is)...>;
//};
//template <unsigned N, _B... _Is> struct build_indices
// : build_indices<N-1, N-1, _Is...> { };
//template < _B... _Is> struct build_indices<0, _Is...>
// : indices<_Is...> { };
public:
using WithDefaultValues =
typename build_indices<_count>::type::WithPow2Values;
当然,我愿意为整个情况提供任何其他选择(在同一模板集中支持标志名称和值等)。
我在ideone中包含了一个“工作”示例:http://ideone.com/NYtUrg - 通过“工作”我的意思是在不使用默认值的情况下编译正常但是使用默认值失败(在它们之间切换#define)。 / p>
谢谢!
答案 0 :(得分:0)
所以我自己想出来了,我想我发布的太快了。
我能够通过上面的build_indices
和indices
模板类中的虚拟模板参数来解决使用给定代码生成的错误。参数必须是一个类型名,因为它们目前有可变积分类型。
(注意:此处仍然使用不正确的_F
名称 - 我已更正我的个人代码以不使用这些保留名称 - 感谢提示)
这是一个有效的解决方案,它使WithValues<...>
模板根据Flags可变参数模板的大小填充2(1,2,4,8,16 ......)的幂。
private:
// dummy class which can be given to a flag-name template
struct _F
{
template <_B _V> inline constexpr
explicit _F(std::integral_constant<_B, _V>) { }
};
// we count the flags, but only in a dummy way
static constexpr unsigned _count = sizeof...(_Fs<_B, _F, 1>);
static inline constexpr
_B pow2(unsigned exp, _B base = 2, _B result = 1)
{
return exp < 1 ?
result :
pow2(exp/2, base*base, (exp % 2) ? result*base : result);
}
template <class dummy, _B... _Is> struct indices
{
using next = indices<dummy, _Is..., sizeof...(_Is)>;
using WithPow2Values = WithValues<pow2(_Is)...>;
};
template <class dummy, unsigned N> struct build_indices
{
using type = typename build_indices<dummy, N-1>::type::next;
};
template <class dummy> struct build_indices<dummy, 0>
{
using type = indices<dummy>;
};
public:
using WithDefaultValues =
typename build_indices<void, _count>::type::WithPow2Values;