gpt4 book ai didi

c++ - std::map 默认值(仅移动类型)

转载 作者:行者123 更新时间:2023-11-28 04:30:45 25 4
gpt4 key购买 nike

如何解决std::map default value对于只移动类型?看起来问题是谁拥有这个对象

  • 如果该值存在,则 map 保持所有者状态,并且必须返回 T const&
  • 如果值不存在,调用者将是所有者,并且必须返回一个T(从默认值移动构造)。

但是无论返回值来自哪里,函数的返回类型必须相同。因此不可能从临时文件中获取默认值。我说得对吗?

你可以使用 std::shared_ptr 但那是作弊。

最佳答案

这可以通过代理对象来实现。

template <typename T>
class PossiblyOwner
{
public:
struct Reference {};

PossiblyOwner(const PossiblyOwner & other)
: m_own(other.m_own),
m_ref(m_own.has_value() ? m_own.value() : other.m_ref)
{}
PossiblyOwner(PossiblyOwner && other)
: m_own(std::move(other.m_own)),
m_ref(m_own.has_value() ? m_own.value() : other.m_ref)
{}

PossiblyOwner(T && val) : m_own(std::move(val)), m_ref(m_own.value()) {}
PossiblyOwner(const T & val) : m_own(val), m_ref(m_own.value()) {}
PossiblyOwner(Reference, const T & val) : m_ref(val) {}
const T& value () const { return m_ref; }
operator const T& () const { return m_ref; }

// convenience operators, possibly also define ->, +, etc.
// but they are not strictly needed
auto operator *() const { return *m_ref; }
private:
std::optional<T> m_own;
const T & m_ref;
};

// Not strictly required
template <typename T>
std::ostream & operator<<(std::ostream & out,
const PossiblyOwner<T> & value)
{
return out << value.value();
}
template <typename Container, typename Key, typename ...DefaultArgs>
auto GetOrDefault(const Container & container, const Key & key,
DefaultArgs ...defaultArgs)
-> PossiblyOwner<decltype(container.find(key)->second)>
{
auto it = container.find(key);
using value_type = decltype(it->second);
using ret_type = PossiblyOwner<value_type>;
if (it == container.end())
return {value_type(std::forward<DefaultArgs>(defaultArgs)...)};
else
return {typename ret_type::Reference{}, it->second};
}

那么用法可以是:

int main()
{
std::map<int, std::unique_ptr<std::string>> mapping;
mapping.emplace(1, std::make_unique<std::string>("one"));
mapping.emplace(2, std::make_unique<std::string>("two"));
mapping.emplace(3, std::make_unique<std::string>("three"));
std::cout << *GetOrDefault(mapping, 0,
std::make_unique<std::string>("zero")) << "\n";
std::cout << *GetOrDefault(mapping, 1,
std::make_unique<std::string>("one1")) << "\n";
std::cout << *GetOrDefault(mapping, 3,
new std::string("three1")) << "\n";
}

编辑

我注意到 PossiblyOwner<T> 的默认复制构造函数导致未定义的行为,所以我不得不定义一个非默认的复制和移动构造函数。

关于c++ - std::map 默认值(仅移动类型),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53023402/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com