我正在尝试学习 std::reference_wrapper 和 std::ref 的使用及其用例。 这是我写的示例代码,请帮我解决编译错误,如果你能深入解释这个问题那就太好了。
#include <iostream>
#include <limits>
#include <unordered_map>
#include <functional>
class MyClass
{
public:
struct Data
{
int id;
Data() : id(std::numeric_limits<int>::max()) {}
};
std::unordered_map<std::string, Data> keyToData_;
Data& getOrCreateData(const std::string &key)
{
auto it = keyToData_.find(key);
if (it == keyToData_.end())
{
it = keyToData_.insert({key, Data()}).first;
}
return it->second;
}
void addBuffer(const std::string &key, std::reference_wrapper<Data> && r)
{
buffer_[key] = r;
}
private:
std::unordered_map<std::string, std::reference_wrapper<Data>> buffer_;
};
int main(int, char **argv)
{
MyClass dataManager{};
auto &r1 = dataManager.getOrCreateData("key1");
r1.id = 1;
dataManager.addBuffer("key1", std::ref(r1));
}
我想存储数据的引用,数据会在代码的同时不断更新,就像数据的脏位引用一样,在我的程序结束时我只需要更新这些值而无需迭代整个 unordered_map。我不想在此过程中创建任何副本以避免性能问题,而且我也避免使用shared_ptr,因为我认为在这种情况下使用原始指针会更好(我知道该对象不会超出范围)。有没有更好的办法?
这是错误 -
.\sample.cpp:30:16: required from here
C:/msys64/mingw64/include/c++/11.3.0/tuple:1824:9: error: no matching function for call to 'std::reference_wrapper<MyClass::Data>::reference_wrapper()'
1824 | second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from C:/msys64/mingw64/include/c++/11.3.0/functional:58,
from .\sample.cpp:4:
C:/msys64/mingw64/include/c++/11.3.0/bits/refwrap.h:321:9: note: candidate: 'template<class _Up, class, class> std::reference_wrapper<_Tp>::reference_wrapper(_Up&&) [with _Up = _Up; <template-parameter-2-2> = <template-parameter-1-2>; <template-parameter-2-3> = <template-parameter-1-3>; _Tp = MyClass::Data]'
321 | reference_wrapper(_Up&& __uref)
| ^~~~~~~~~~~~~~~~~
C:/msys64/mingw64/include/c++/11.3.0/bits/refwrap.h:321:9: note: template argument deduction/substitution failed:
In file included from C:/msys64/mingw64/include/c++/11.3.0/bits/hashtable_policy.h:34,
from C:/msys64/mingw64/include/c++/11.3.0/bits/hashtable.h:35,
from C:/msys64/mingw64/include/c++/11.3.0/unordered_map:46,
from .\sample.cpp:3:
C:/msys64/mingw64/include/c++/11.3.0/tuple:1824:9: note: candidate expects 1 argument, 0 provided
1824 | second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from C:/msys64/mingw64/include/c++/11.3.0/functional:58,
from .\sample.cpp:4:
C:/msys64/mingw64/include/c++/11.3.0/bits/refwrap.h:326:7: note: candidate: 'constexpr std::reference_wrapper<_Tp>::reference_wrapper(const std::reference_wrapper<_Tp>&) [with _Tp = MyClass::Data]'
326 | reference_wrapper(const reference_wrapper&) = default;
| ^~~~~~~~~~~~~~~~~
C:/msys64/mingw64/include/c++/11.3.0/bits/refwrap.h:326:7: note: candidate expects 1 argument, 0 provided
我尝试过像这样更改函数声明 -
void addBuffer(const std::string &key, Data &r)
{
buffer_[key] = std::ref(r);
}
std::map::operator[]
,要求mapped_type
是默认可构造。由于 std::reference_wrapper<Data>
(即 mapped_type
的 std::unordered_map<std::string, std::reference_wrapper<Data>> buffer_;
)不是默认可构造的,因此您会收到错误。
std::map::emplace
将键值添加到 buffer_
,就会将一个新元素插入到容器中,使用就地构建提供的参数,如果容器中不存在具有指定键的元素。
buffer_.emplace(key, std::move(r));