我正在尝试实现zip
功能。 zip
的参数均为wrapped<Ti>
,其中Ti
因参数而异。
zip
获取这些wrapped<Ti>
并生成wrapped<tuple<T1&,T2&,...TN&>>
,或者换句话说,包含tuple
对其参数的引用。引用应保留const
- ness。
这是我第一次使用一个参数刺向zip
,这通常不起作用:
#include <utility>
#include <tuple>
// implement forward_as_tuple as it is missing on my system
namespace ns
{
template<typename... Types>
std::tuple<Types&&...>
forward_as_tuple(Types&&... t)
{
return std::tuple<Types&&...>(std::forward<Types>(t)...);
}
}
template<typename T>
struct wrapped
{
wrapped(T &&x)
: m_x(std::forward<T>(x))
{}
T m_x;
};
template<typename T>
wrapped<std::tuple<T&&>>
zip(wrapped<T> &&x)
{
auto t = ns::forward_as_tuple(std::forward<T>(x.m_x));
return wrapped<std::tuple<T&&>>(t);
}
int main()
{
wrapped<int> w1(13);
wrapped<int> &ref_w1 = w1;
// OK
zip(ref_w1);
const wrapped<int> &cref_w1 = w1;
// XXX won't compile when passing a const reference
zip(cref_w1);
return 0;
}
有没有办法用zip
的单个版本实现一般的,可变的情况?
答案 0 :(得分:1)
不可否认,我没有处理可变参数模板的C ++ 0x编译器,所以我无法测试它。但这可能会成功。
template<typename T>
struct wrapped
{
wrapped(T &&x)
: m_x(std::forward<T>(x))
{}
typedef T type;
T m_x;
};
template<typename... Types>
wrapped<std::tuple<Types&&...>> zip(wrapped<Types>&&... x)
{
return wrapped<std::tuple<Types&&...>>(std::tuple<Types&&...>(std::forward<Types>(x.m_x)...));
}
我不完全确定如此调用zip
是否合法:
zip(wrapped<T1>(value1), wrapped<T2>(value2));
您可能必须明确限定通话:
zip<T1, T2>(wrapped<T1>(value1), wrapped<T2>(value2));
答案 1 :(得分:1)
这是我到达的解决方案:
#include <utility>
#include <tuple>
#include <cassert>
template<typename T>
struct wrapped
{
wrapped(T &&x)
: m_x(std::forward<T>(x))
{}
T m_x;
};
template<typename Tuple>
wrapped<Tuple> make_wrapped_tuple(Tuple &&x)
{
return wrapped<Tuple>(std::forward<Tuple>(x));
}
template<typename... WrappedTypes>
decltype(make_wrapped_tuple(std::forward_as_tuple(std::declval<WrappedTypes>().m_x...)))
zip(WrappedTypes&&... x)
{
return make_wrapped_tuple(std::forward_as_tuple(x.m_x...));
}
int main()
{
wrapped<int> w1(1);
wrapped<int> w2(2);
wrapped<int> w3(3);
wrapped<int> w4(4);
auto z1 = zip(w1,w2,w3,w4);
z1.m_x = std::make_tuple(11,22,33,44);
assert(w1.m_x == 11);
assert(w2.m_x == 22);
assert(w3.m_x == 33);
assert(w4.m_x == 44);
const wrapped<int> &cref_w1 = w1;
auto z2 = zip(cref_w1, w2, w3, w4);
// does not compile, as desired
// z2.m_x = std::make_tuple(111,222,333,444);
return 0;
}
让zip
取代WrappedTypes...
代替wrapped<T>...
并不是一个令人满意的解决方案,但它确实有效。
答案 2 :(得分:0)
template<typename T>
struct wrapped
{
wrapped(T &&x)
: m_x(std::forward<T>(x))
{}
typedef T type;
T m_x;
};
template<typename... Types>
wrapped<std::tuple<T&&...>> zip(wrapped<Types>... &&x)
{
return G+