template <class... T_values>
class Thing {
public:
void something(T_values... values) {
tuple_ = std::tuple<T_values...>(values...);
}
void do_something_with_values() {
call_yadda_with_tuple(tuple_,
std::index_sequence_for<T_value...>())
}
void yadda(T... values);
private:
//The helper method.
template<std::size_t... Is>
void call_yadda_with_tuple(const std::tuple<T_values...>& tuple,
std::index_sequence<Is...>) {
yadda(std::get<Is>(tuple)...);
}
std::tuple<T_values...> tuple_;
};
以上源代码来自:https://www.murrayc.com/permalink/2015/12/05/modern-c-variadic-template-parameters-and-tuples/
我想问一些问题:
std::index_sequence_for<T_value...>())
?yadda(std::get<Is>(tuple)...);
中有Is
而不是Is...
?因此,Is
是什么意思?解包(扩展)类型包中的Is...
但Is
是什么。 std::get
符合(1) - (8)
(http://en.cppreference.com/w/cpp/utility/tuple/get)call_yadda_with_tuple
获得std::index_sequence<Is...>
。
毕竟,这个论点是无名的,所以它没用。我认为它与演绎类型有关,但我看不出它有什么帮助?答案 0 :(得分:2)
什么返回std :: index_sequence_for())?
假设T_value ...是T,T,T(即3种类型......)
std::index_sequence<0, 1, 2>
为什么在yadda(std :: get(tuple)...);有而不是是......?因此,这是什么意思?是......在解包(扩展)类型包中,但是什么是。
Is
代表'当前值',而Is...
正在解包。尾随...
导致解包使用Is
的表达式。
特别是,哪个std :: get适合于(1) - (8)(http://en.cppreference.com/w/cpp/utility/tuple/get)
在这种情况下,元组引用为const std::tuple<T_values...>&
,因此它将为3。
为什么call_yadda_with_tuple获取std :: index_sequence。毕竟,这个论点是无名的,所以它没用。我想它与演绎类型有关,但我看不出它有什么帮助呢?
只会导致Is...
存在,因此您可以扩展序列中的所有Is
。
编辑:
以下是一个评论示例,希望能够解释正在发生的事情
#include <utility>
#include <tuple>
#include <string>
#include <iostream>
// for any value I, write a comma and space to stdout
// (i.e. ignore the value I)
template<std::size_t I>
void emit_sep()
{
std::cout << ", ";
}
// specialise for when I is zero... no comma in this case
template<>
void emit_sep<0>()
{
}
// emit and value at some position I. Use emit_sep<I> to determine whether
// to print a separator
template<std::size_t I, class T>
void emit(const T& t)
{
emit_sep<I>();
std::cout << t;
}
// given a tuple type and a sequence of integers (Is...) emit the value
// at each index position of the tuple. Take care to emit a separator only
// before each element after the first one
template<class Tuple, size_t...Is>
void impl_show_it(const Tuple& tup, std::index_sequence<Is...>)
{
using expand = int[];
std::cout << "here are the indexes in the index_sequence: ";
// the following line will expand (in our example) to:
// void(int[] { 0,
// (emit<0>(0), 0),
// (emit<1>(1), 0),
// (emit<2>(2), 0),
// });
// and the optimiser will remove the operations which have no observable
// side-effects (namely, building an array of ints which is never used)
// so the code emitted will be equivalent to:
// emit<0>(0); emit<1>(1); emit<2>(2);
//
void(expand {
0,
(emit<Is>(Is), 0)...
});
std::cout << std::endl;
std::cout << "here are the values in the tuple: ";
void(expand {
0,
(emit<Is>(std::get<Is>(tup)), 0)...
});
std::cout << std::endl;
}
// for some tuple type, compute the size of the tuple, build an index sequence
// representing each INDEX in the tuple and then use that sequence to call
// impl_show_it in order to actually perform the write
template<class Tuple>
void show_it(const Tuple& tup)
{
constexpr auto tuple_size = std::tuple_size<Tuple>::value;
auto sequence = std::make_index_sequence<tuple_size>();
impl_show_it(tup, sequence);
}
// make a tuple and then show it on stdout
int main()
{
auto t = std::make_tuple(6, std::string("hello"), 5.5);
show_it(t);
}
预期结果:
here are the indexes in the index_sequence: 0, 1, 2
here are the values in the tuple: 6, hello, 5.5