如何将一个向量的元素引用复制到另一个向量?
How to copy references of elements of one vector to another vector?
我有一个 vector
:
std::vector<island> sea;
现在我想在另一个 vector
中保存指向此 vector
的所有元素的指针。但只是为了个人练习,我想以一种花哨的 C++ 风格来做这件事,所以我输入的不是 std::vector<const island*> p_sea
:
std::vector<std::reference_wrapper<const island>> r_sea;
现在我想用参考资料填充这个新的 vector
:
std::transform(sea.begin(), sea.end(),
std::back_inserter(r_sea),
std::cref<island>
);
我的理解是,从 cppreference 文章中,transform
的第四个参数应该是一个函数,它对源范围的元素和目标范围的 returns 元素进行常量引用;这正是 std::cref<island>
所做的:它将 const island&
作为参数,returns std::reference_wrapper<const island>
。所以我认为这应该有效??
然而,它没有:
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <iterator>
struct island {
long long x,y; //coords
};
int main() {
std::vector<island> sea;
std::vector<std::reference_wrapper<const island>> r_sea;
std::transform(sea.begin(), sea.end(),
std::back_inserter(r_sea),
std::cref<island>
);
return 0;
}
这会导致以下编译错误:
prog.cpp: In function ‘int main()’:
prog.cpp:19:5: error: no matching function for call to ‘transform(std::vector<island>::iterator, std::vector<island>::iterator, std::back_insert_iterator<std::vector<std::reference_wrapper<const island> > >, <unresolved overloaded function type>)’
);
^
In file included from /usr/include/c++/6/algorithm:62:0,
from prog.cpp:3:
/usr/include/c++/6/bits/stl_algo.h:4166:5: note: candidate: template<class _IIter, class _OIter, class _UnaryOperation> _OIter std::transform(_IIter, _IIter, _OIter, _UnaryOperation)
transform(_InputIterator __first, _InputIterator __last,
^~~~~~~~~
/usr/include/c++/6/bits/stl_algo.h:4166:5: note: template argument deduction/substitution failed:
prog.cpp:19:5: note: could not resolve address from overloaded function ‘cref<island>’
);
^
In file included from /usr/include/c++/6/algorithm:62:0,
from prog.cpp:3:
/usr/include/c++/6/bits/stl_algo.h:4203:5: note: candidate: template<class _IIter1, class _IIter2, class _OIter, class _BinaryOperation> _OIter std::transform(_IIter1, _IIter1, _IIter2, _OIter, _BinaryOperation)
transform(_InputIterator1 __first1, _InputIterator1 __last1,
^~~~~~~~~
/usr/include/c++/6/bits/stl_algo.h:4203:5: note: template argument deduction/substitution failed:
prog.cpp:19:5: note: could not resolve address from overloaded function ‘cref<island>’
);
我做错了什么?
...我又回到了邪恶的 C 指针。
将 std::cref<island>
替换为 [](auto&x){return std::cref<island>(x);}
,假设 c++14。
在 c++11 中,将 auto
替换为 island const
。
cref
有重载,不能将重载集作为对象传递,因为重载集不是对象。
std::cref
过载。仅仅指定模板参数不足以消除重载之间的歧义。您有两个选择:
投射
static_cast<std::reference_wrapper<const island>(*)(const island&)>(std::cref<island>)
将名称提升为仿函数对象(lambda)。就像@Yakk 提议的那样。
我有一个 vector
:
std::vector<island> sea;
现在我想在另一个 vector
中保存指向此 vector
的所有元素的指针。但只是为了个人练习,我想以一种花哨的 C++ 风格来做这件事,所以我输入的不是 std::vector<const island*> p_sea
:
std::vector<std::reference_wrapper<const island>> r_sea;
现在我想用参考资料填充这个新的 vector
:
std::transform(sea.begin(), sea.end(),
std::back_inserter(r_sea),
std::cref<island>
);
我的理解是,从 cppreference 文章中,transform
的第四个参数应该是一个函数,它对源范围的元素和目标范围的 returns 元素进行常量引用;这正是 std::cref<island>
所做的:它将 const island&
作为参数,returns std::reference_wrapper<const island>
。所以我认为这应该有效??
然而,它没有:
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <iterator>
struct island {
long long x,y; //coords
};
int main() {
std::vector<island> sea;
std::vector<std::reference_wrapper<const island>> r_sea;
std::transform(sea.begin(), sea.end(),
std::back_inserter(r_sea),
std::cref<island>
);
return 0;
}
这会导致以下编译错误:
prog.cpp: In function ‘int main()’:
prog.cpp:19:5: error: no matching function for call to ‘transform(std::vector<island>::iterator, std::vector<island>::iterator, std::back_insert_iterator<std::vector<std::reference_wrapper<const island> > >, <unresolved overloaded function type>)’
);
^
In file included from /usr/include/c++/6/algorithm:62:0,
from prog.cpp:3:
/usr/include/c++/6/bits/stl_algo.h:4166:5: note: candidate: template<class _IIter, class _OIter, class _UnaryOperation> _OIter std::transform(_IIter, _IIter, _OIter, _UnaryOperation)
transform(_InputIterator __first, _InputIterator __last,
^~~~~~~~~
/usr/include/c++/6/bits/stl_algo.h:4166:5: note: template argument deduction/substitution failed:
prog.cpp:19:5: note: could not resolve address from overloaded function ‘cref<island>’
);
^
In file included from /usr/include/c++/6/algorithm:62:0,
from prog.cpp:3:
/usr/include/c++/6/bits/stl_algo.h:4203:5: note: candidate: template<class _IIter1, class _IIter2, class _OIter, class _BinaryOperation> _OIter std::transform(_IIter1, _IIter1, _IIter2, _OIter, _BinaryOperation)
transform(_InputIterator1 __first1, _InputIterator1 __last1,
^~~~~~~~~
/usr/include/c++/6/bits/stl_algo.h:4203:5: note: template argument deduction/substitution failed:
prog.cpp:19:5: note: could not resolve address from overloaded function ‘cref<island>’
);
我做错了什么?
...我又回到了邪恶的 C 指针。
将 std::cref<island>
替换为 [](auto&x){return std::cref<island>(x);}
,假设 c++14。
在 c++11 中,将 auto
替换为 island const
。
cref
有重载,不能将重载集作为对象传递,因为重载集不是对象。
std::cref
过载。仅仅指定模板参数不足以消除重载之间的歧义。您有两个选择:
投射
static_cast<std::reference_wrapper<const island>(*)(const island&)>(std::cref<island>)
将名称提升为仿函数对象(lambda)。就像@Yakk 提议的那样。