【发布时间】:2015-09-28 12:05:21
【问题描述】:
在以下代码中:
#include <iostream>
#include <utility>
#include <set>
template <typename... Args>
void f(Args... args) {
std::cout << sizeof...(Args) << " elements.\n";
}
template <std::size_t... Is>
void g (std::index_sequence<Is...>, const std::set<int>& set) {
f((set.find(Is) == set.end() ? Is : 2*Is)...);
}
int main() {
g (std::make_index_sequence<10>{}, {1,3,7,8});
}
如果set.find(Is) == set.end(),我希望f((set.find(Is) == set.end() ? Is : 2*Is)...); 使用Is,否则什么都不使用(而不是2*Is)。因此传递的参数数量不是固定的。如何实现?
编辑: 抱歉,我把问题简化得太多了。下面的代码更能反映真正的问题:
#include <iostream>
#include <utility>
#include <tuple>
template <typename... Args>
void f(Args... args) {
std::cout << sizeof...(Args) << " elements.\n";
}
struct NullObject {};
template <typename Tuple, std::size_t... Is>
void g (std::index_sequence<Is...>, const Tuple& tuple) {
f ((std::get<Is>(tuple) != std::get<Is+1>(tuple) ? std::get<Is>(tuple) : NullObject{})...);
}
int main() {
g (std::make_index_sequence<8>{}, std::make_tuple(2,1.5,'a','a',true,5,5,false));
}
由于三元运算符传递的混合类型,上面没有编译,但我想你可以在这里看到我的想法。如果条件为std::get<Is>(tuple) != std::get<Is+1>(tuple),我不想传递任何内容,所以我传递NullObject{},然后以某种方式尝试从f 的参数中删除所有NullObjects,以获得传递给f 的真实参数。
【问题讨论】:
-
你不能,不是用 三元 表达式。为什么不使用
if语句?或者在三元表达式中调用f函数,而不是在f调用中使用三元表达式。 -
如果您可以通过编译类型替换您的
std::set内容,您可以执行以下操作:Demo -
@Jarod42 对不起,我把问题简化得太多了,我更新了问题。我不确定你的技术是否仍然适用。
-
@prestokeys:如果您将(运行时)变量转换为类型(在
std::integral_constant的帮助下),您可以正确调用f,但无论如何它都需要辅助函数。
标签: c++ templates c++11 variadic