如何从尾部而不是头部拉出可变参数模板参数?
由于愚蠢的原因,我不会进入这里,我需要注释掉的行才能工作,而它上面的行则不起作用:
template<uint _N, typename... _Args>
struct PartialTuple;
template<uint _N, typename _Arg, typename... _Args>
struct PartialTuple<_N, _Arg, _Args...>: PartialTuple<_N-1, _Args...> {};
template<typename _Arg, typename... _Args>
struct PartialTuple<0, _Arg, _Args...>
{
typedef std::tuple<_Arg, _Args...> type;
};
int main()
{
// I want this to not work...
PartialTuple<1, std::string, std::string, int, int>::type A{"test", 5, 1};
// I want this to work...
//PartialTuple<1, std::string, std::string, int, int>::type B{"test", "test", 5};
}
我尝试将 _Arg
与 _Args...,但这不会编译(至少在 GCC 4.6 中):
error: parameter pack argument ‘_Args ...’ must be at the end of the template argument list
如何从尾部而不是从头部拉出项目?
For silly reasons I'll not go into here, I need the commented out line to work and the line above it it to not work:
template<uint _N, typename... _Args>
struct PartialTuple;
template<uint _N, typename _Arg, typename... _Args>
struct PartialTuple<_N, _Arg, _Args...>: PartialTuple<_N-1, _Args...> {};
template<typename _Arg, typename... _Args>
struct PartialTuple<0, _Arg, _Args...>
{
typedef std::tuple<_Arg, _Args...> type;
};
int main()
{
// I want this to not work...
PartialTuple<1, std::string, std::string, int, int>::type A{"test", 5, 1};
// I want this to work...
//PartialTuple<1, std::string, std::string, int, int>::type B{"test", "test", 5};
}
I tried swapping _Arg
with _Args...
, but that won't compile (at least in GCC 4.6):
error: parameter pack argument ‘_Args ...’ must be at the end of the template argument list
How can I pull items off from the tail instead of from the head?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是一个解决方案:我不从后面截断
N
,而是从前面截断sizeof...(Args) - N
:Here's a solution: Instead of truncating
N
from the back, I just truncatesizeof...(Args) - N
from the front:我整晚都在玩它,终于找到了一些东西(改变了我的外壳以匹配 STL):
作为额外的好处,我还有
reverse_tuple
,如果我需要它的话。I've been playing with it all night and finally got something to work (changed my casing to match the STL):
As an added bonus, I also have
reverse_tuple
, should I ever need it.我让我的代码有点像 Haskell 中的列表 - 因为,TMP 是 C++ 中的纯函数式语言。
add_to_pack
相当于 Haskell 的列表构造函数(:)
。drop_from_end
实现为(用 Haskell 表示法)\x list -> take (length list - x) list
,其中take n
仅获取列表的前n
个元素。我想您可以直接使用
std::tuple
而不是pack
,但我更喜欢这个解决方案,因为它不会滥用 tuple 作为模板参数包持有者。 :)这是代码:
这是工作中的代码:来自 ideone.com。
take
结构或多或少相当于以下 Haskell 代码:I've made my code work a little bit like lists in Haskell - because, well, TMP is purely functional language inside C++.
add_to_pack
is equivalent to Haskell's list constructor(:)
.drop_from_end
is implemented as (in Haskell notation)\x list -> take (length list - x) list
, wheretake n
just takes firstn
elements of the list.I suppose you could use
std::tuple
directly instead ofpack
, but I liked this solution better, because it doesn't misuse tuple as template parameter pack holder. :)Here's the code:
And here's the code at work: via ideone.com.
The
take
struct is more or less equivalent to following Haskell code:我使用 Boost.MPL 和 Boost.Fusion 做了类似的事情:使用 MPL 工具(例如
push_back
)计算类型序列,然后将其转换为fusion::vector
fusion::as_vector 和 MPL 适配器。不过,我已经有一个助手将 fusion::vector 转换为 std::tuple 。I have done something similar using Boost.MPL and Boost.Fusion: compute the type sequence using the MPL facilities such as
push_back
, then convert it to afusion::vector
withfusion::as_vector
and MPL adaptors. I already had a helper to convert afusion::vector
tostd::tuple
though.