std::reference_wrapper不是默认构造的.所以我不能写任何:
std::vector<std::reference_wrapper<int>> vec(10);
std::array<std::reference_wrapper<int>, 3> arr;
Run Code Online (Sandbox Code Playgroud)
但是,令我惊讶的是,您可以调用对象std::vector::reserve向量的成员函数std::reference_wrapper并有效地更改其容量.
std::vector<std::reference_wrapper<int>> vec;
vec.reserve(10);
Run Code Online (Sandbox Code Playgroud)
这怎么可能,因为std::reference_wrapper没有默认构造函数?
我有vector一些包含的引用类型reference_wrapper.由于我需要按顺序填充此容器,我正在尝试为容器设置初始大小:
vector<std::reference_wrapper<T>> v(5);
v[3] = ..
v[2] = ..
v[4] = ..
v[5] = ..
v[1] = ..
Run Code Online (Sandbox Code Playgroud)
这无法编译,如下所示:
error: no matching function for call to ‘std::reference_wrapper<int>::reference_wrapper()’
Run Code Online (Sandbox Code Playgroud)
是否有解决方法使这项工作或我必须vector<T*>为此目的使用?
以下是两种不同类型的std :: vector,作为示例:
std::vector<std::reference_wrapper<MyClass>> rv;
std::vector<MyClass> v;
Run Code Online (Sandbox Code Playgroud)
在它们之间分配的可能方法是:
for (const auto& mc : rv) {
v.push_back(mc.get());
}
Run Code Online (Sandbox Code Playgroud)
有用.但丑陋而且可能很慢.与比较相同:
bool is_same(std::vector<MyClass>& v, std::vector<std::reference_wrapper<MyClass>>& rv) {
if (v.size()!=rv.size()) {
return false;
}
for (size_t i = 0; i < v.size(); v++) {
if (v[i]!=rv[i].get()) {
return false;
}
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法来完成这项工作?聪明而快速.
所以我std::reference_wrapper在 C++11 中发现了这个奇特的东西,我发现它在未来的程序开发中可能很有用。我玩了一会儿,我认为它可以在某些情况下取代旧的参考以获得更好的使用,直到我遇到以下错误:
#include <iostream>
#include <functional>
class testbench {
public:
int ownerid = 5;
bool camper = false;
};
class testing {
public:
testing(testbench &x);
int quack = 3;
std::reference_wrapper <testbench> camper;
};
testing::testing(testbench &x):camper(x) {
}
int main() {
testbench tempo;
testing test_a (tempo);
std::cout << test_a.camper.ownerid;
}
Run Code Online (Sandbox Code Playgroud)
这会导致 gcc 中出现错误(我使用 Code::Blocks 作为编辑器,使用 gcc 作为编译器)
'class std::reference_wrapper<testbench>' has no member named 'ownerid'
Run Code Online (Sandbox Code Playgroud)
如果线
std::reference_wrapper <testbench> camper;
Run Code Online (Sandbox Code Playgroud)
更改为:
testbench &camper;
Run Code Online (Sandbox Code Playgroud)
然后一切都按照我的预期进行。
我该如何解决这个问题,或者这只是我 std::reference_wrapper作为参考的一般改进的误解?
根据我的理解,引用包装器只是引用的包装器,没有什么特别的。但是,当作为函数参数传递时,为什么它被视为函数内部的引用本身(而不是包装器)呢?
#include <iostream>
#include <functional>
using namespace std;
void f(int& x){
cout<<"f on int called"<<endl;
}
void f(reference_wrapper<int>& x){
cout<<"f on wrapper called"<<endl;
}
int main(){
int x = 10;
f(ref(x)); // f on int called, why?
reference_wrapper<int> z = ref(x);
f(z); // f on wrapper called, this makes sense though
}
Run Code Online (Sandbox Code Playgroud)
为什么 ref(x) 在函数调用中被视为 x 本身?我遇到这个问题是因为我试图理解在不同线程之间传递数据时 ref() 的使用。我认为 ref() 是必要的,因此任何带有“&”的函数参数都不需要重写以避免线程相互干扰。但是为什么线程可以将 ref(x) 视为 x 而不使用 x.get() 呢?
我最近开始使用这std::reference_wrapper门课.当替换原始引用的某些用法时,我注意到我没有必要使用该get()函数将reference_wrappers作为参数传递给采用普通引用的函数.
void foo(const T& a);
//...
T obj;
std::reference_wrapper<const T> ref(obj);
foo(ref); //works!
//foo(ref.get()); also works, but I expected that it would be required
Run Code Online (Sandbox Code Playgroud)
std::reference_wrapper当它传递给函数时,如何隐式转换为原始引用?
我有一个大的std::vector<int> a,但我想只在它的一个子集上工作.我们的想法是创建一个std::vector<reference_wrapper<int> > refa只包含所述子集的部分(在mwe中,所有元素1 a<< 4).然后我想传递refa给期望一个std::vector<int>或std::vector<int>&作为参数的函数(因为我也想使用它们a).a可以很大,我想避免多次选择.
问题
如何正确传递refa给函数?我想要的是bar(refa)和foobar(refa)工作.
有没有更好的方法来解决问题,而不改变功能(太多)?
码
#include <functional>
#include <iostream>
#include <vector>
int foo(int &a)
{
a++;
return 0;
}
int bar(std::vector<int> &va)
{
for(auto &vaa : va)
vaa++;
return 0;
}
int foobar(std::vector<int> va)
{
for(auto &vaa : va)
vaa++;
return 0;
}
int main()
{
std::vector<int> a= {1, 2, 3, 4, 5};
std::vector<std::reference_wrapper<int> …Run Code Online (Sandbox Code Playgroud) 在下面的代码中,目标是具有reference_wrapper<int> b这样一种特性,即当a更改时b也会更改,但是不允许相反,也就是说,a更改时不应b更改。我尝试了两种方法:第7行和第8行。第7行导致编译器抱怨它无法从第8行编译时毫无问题地转换为int,const int但是结果却不是我想要的(a更改时b更改了)。任何的想法?
1. #include <iostream>
2. #include <functional>
3. using namespace std;
4.
5. int main() {
6. int a = 1;
7. //reference_wrapper<const int> b = ref(a);
8. //const reference_wrapper<int> b = ref(a);
9. return 0;
10. }
Run Code Online (Sandbox Code Playgroud) 我对涉及引用和std :: reference_wrapper的一些代码感到困惑,我不清楚这是否是我的错,因为我误解了引用包装器的工作原理或者我遇到编译器错误.
我有一个简单的映射,将对象的引用与复杂类配对:
std::unordered_map<Object const &obj, int32_t value> myMap;
Run Code Online (Sandbox Code Playgroud)
(为简单起见,我明确地省略了地图编译所需的哈希和相等的仿函数)
由于我不能直接在地图中使用引用,我使用它的引用包装:
std::unordered_map<std::reference_wrapper<const Object> obj, int32_t value> myMap;
Run Code Online (Sandbox Code Playgroud)
现在,我的地图填充在以下功能中:
void myFunction(Object const &obj, int32_t value)
{
...
myMap.emplace(std::make_pair(obj, value));
}
Run Code Online (Sandbox Code Playgroud)
但该代码虽然编译,但不起作用.但是,这个按预期工作:
void myFunction(Object const &obj, int32_t value)
{
...
myMap.emplace(std::pair<std::reference_wrapper<const Object>, int32_t>(obj, value));
}
Run Code Online (Sandbox Code Playgroud)
(在第二个版本中注意我还没有明确地为obj构建一个引用包装器)
所以,我的怀疑是:
我是否误解了参考包装器的用法?从引用到reference_wrapper没有隐式转换?如果没有,为什么代码首先编译?
或者这是std :: make_pair中的已知问题/缺陷无法正确扣除传递给它的类型?
我目前正在从事大型代码项目,并希望借此机会学习和使用名称空间。我定义的所有类都驻留在单个名称空间Test中。
我的一个类(在这里称为Thing)具有唯一的ID。我需要能够保存对某些事物的引用的std :: vector,因此我正在使用std :: reference_wrappers。在程序中的某些点,我需要从向量中删除某些std :: reference_wrappers,所以我使用std :: find:
#include <algorithm>
#include <functional>
#include <vector>
namespace Test {
class Thing {
private:
const int id;
public:
Thing(int id);
const int ID() const;
};
}
Test::Thing::Thing(int id) : id(id) { }
const int Test::Thing::ID() const {
return id;
}
inline bool operator==(const Test::Thing& lhs, const Test::Thing& rhs) {
return lhs.ID() == rhs.ID();
}
inline bool operator!=(const Test::Thing& lhs, const Test::Thing& rhs) {
return !(lhs == rhs);
}
int main() { …Run Code Online (Sandbox Code Playgroud)