gnz*_*lbg 14 c++ boost join range
我想做以下事情:
std::vector<int> a = {1,2,3}, b = {4,5,6}, c = {7,8,9};
for(auto&& i : join(a,b,c)) {
i += 1
std::cout << i; // -> 2345678910
}
Run Code Online (Sandbox Code Playgroud)
我试过用boost::range::join,这很好用:
auto r = boost::join(a,b);
for(auto&& i : boost::join(r,c)) {
i += 1;
std::cout << i; // -> 2345678910
}
Run Code Online (Sandbox Code Playgroud)
链接加入,阅读操作工作:
for(auto&& i : boost::join(boost::join(a,b),c))
std::cout << i; // -> 123456789
Run Code Online (Sandbox Code Playgroud)
但是,写作不起作用:
for(auto&& i : boost::join(boost::join(a,b),c)) {
i += 1; // Fails :(
std::cout << i;
}
Run Code Online (Sandbox Code Playgroud)
我的可变连接具有相同的问题,即用于阅读但不用于写入:
template<class C> C&& join(C&& c) { return c; }
template<class C, class D, class... Args>
auto join(C&& c, D&& d, Args&&... args)
-> decltype(boost::join(boost::join(std::forward<C>(c), std::forward<D>(d)),
join(std::forward<Args>(args)...))) {
return boost::join(boost::join(std::forward<C>(c), std::forward<D>(d)),
join(std::forward<Args>(args)...));
}
Run Code Online (Sandbox Code Playgroud)
解决方案:(在评论中见Mehrdad的回答)
template<class C>
auto join(C&& c)
-> decltype(boost::make_iterator_range(std::begin(c),std::end(c))) {
return boost::make_iterator_range(std::begin(c),std::end(c));
}
template<class C, class D, class... Args>
auto join(C&& c, D&& d, Args&&... args)
-> decltype(boost::join(boost::join(boost::make_iterator_range(std::begin(c),std::end(c)),
boost::make_iterator_range(std::begin(d),std::end(d))),
join(std::forward<Args>(args)...))) {
return boost::join(boost::join(boost::make_iterator_range(std::begin(c),std::end(c)),
boost::make_iterator_range(std::begin(d),std::end(d))),
join(std::forward<Args>(args)...));
}
Run Code Online (Sandbox Code Playgroud)
jro*_*rok 12
template<typename SinglePassRange1, typename SinglePassRange2>
joined_range<const SinglePassRange1, const SinglePassRange2>
join(const SinglePassRange1& rng1, const SinglePassRange2& rng2)
template<typename SinglePassRange1, typename SinglePassRange2>
joined_range<SinglePassRange1, SinglePassRange2>
join(SinglePassRange1& rng1, SinglePassRange2& rng2);
Run Code Online (Sandbox Code Playgroud)
当你这样做
for(auto&& i : boost::join(boost::join(a,b), c)) {
// ^^^^ ^^^^ temporary here
// ||
// calls the const ref overload
Run Code Online (Sandbox Code Playgroud)
你得到一个临时的joined_range,因为那些只能绑定到const引用,所以选择了第一个重载,它返回一个不允许修改的范围.
如果你避免临时性,你可以解决这个问题:
#include <boost/range.hpp>
#include <boost/range/join.hpp>
int main()
{
std::vector<int> a = {1,2,3}, b = {4,5,6}, c = {7,8,9};
auto range = boost::join(a,b);
for(int& i : boost::join(range,c)) {
i += 1;
std::cout << i;
}
}
Run Code Online (Sandbox Code Playgroud)
我没有研究过你的可变函数,但问题可能类似.
| 归档时间: |
|
| 查看次数: |
4412 次 |
| 最近记录: |