当(且仅当)对象具有复制构造函数时,如何复制对象?

How to copy an object if (and only if) it has a copy constructor?

本文关键字:复制 对象 何复制 构造函数      更新时间:2023-10-16

上下文:我正在尝试记住模板类的对象。 现在,该类是一个深度嵌套的数据结构,充满了独特的指针,因此没有复制构造函数(因此据我所知,不可能缓存(。 但是,将来,如果复制构造函数可用,我想允许记忆。 我尝试了以下代码:

// some function here... {
static std::unordered_map<State, Result> cache;
return [c, ToValue](State state) {
if (cache.find(state) != cache.end()) {
std::cout << "retrieving Literal from cachen";
if (std::is_copy_constructible<Result>::value) {
return cache[state];
}
}
// calculate and return a Result

此代码无法编译,因为 Result 没有复制构造函数。 有什么办法可以解决这个问题吗? 谷歌是相当无益的。

我假设您遇到的错误是当对象不可复制构造时无法编译return cache[state];。要解决此问题,您可以编写:

if constexpr (std::is_copy_constructible<Result>::value) {
return cache[state];
}

如果您仍然遇到问题,请发布出现错误的 MCVE。

正如其他人所评论的那样,这个问题定义不明确且有点混乱,但是您是否需要实际复制对象才能缓存它?

其实不然。 您可以使用std::shared_ptr在创建者、任何使用者和缓存之间共享对象的所有权。 如果不出意外,如果您的对象是复杂的对象,这将更有效。 它也适用于任何类型的对象,无论是否可复制。

示例(我将使用单词Key而不是State,因为我希望这是显而易见的原因(。

鉴于这些声明:

class MyKey
{
// ....
};
class MyCacheableObject
{
// Constructor
MyCacheableObject (int a, int b, int c) { ... }
// ...
};
static std::unordered_map<MyKey, std::shared_ptr<MyCacheableObject>> cache;  // or std::map

您可以这样做(请注意,还有其他方法可以制作std::shared_ptr,请参阅此处(:

std::shared_ptr<MyCacheableObject> CreateCacheableObject (int a, int b, int c)
{
return std::make_shared<MyCacheableObject> (MyCacheableObject (a, b, c));
}

然后,假设您有一个密钥,您计划稍后用于从缓存中检索对象,您可以执行以下操作:

MyKey someKey = ...;
std::shared_ptr<MyCacheableObject> newObject = CreateCacheableObject (1, 2, 3);
// ... setup / use `newObject` in whatever way is appropriate to your use-case 
cache [someKey] = newObject;

当然,您可以通过以下方式从缓存中检索对象(如果它在那里(:

auto retrievedObject = cache.find (someKey)
if (retrievedObject != cache.end())
...

所以这个问题根本不是关于对象是否可复制。 这是关于(共享(所有权的,std::shared_ptr为您处理所有这些,您真的不必考虑它。 哎呀。

这里有一个现场演示,以显示这一切都已编译。