上下文:我正在尝试记住模板类的对象。现在,该类是一个深度嵌套的数据结构,充满了独特的指针,因此没有复制构造函数(据我所知,因此不可能缓存)。但是,将来,如果有可用的复制构造函数,我想允许进行memoization。我尝试了以下代码:
// 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 cache\n";
if (std::is_copy_constructible<Result>::value) {
return cache[state];
}
}
// calculate and return a Result
此代码无法编译,因为Result没有复制构造函数。有没有办法解决这个问题?谷歌非常无益。
答案 0 :(得分:1)
正如其他人所评论的那样,问题是定义不明确而且有点困惑,但你是否需要实际复制一个对象才能缓存它?
实际上,没有。您可以使用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
,请参阅here):
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
为你照顾所有这些,你真的不必考虑它。 Oy vay。
有一个现场演示,以显示所有这些都编译,here。
答案 1 :(得分:1)
我认为你得到的错误是当对象不是可复制构造时,if constexpr (std::is_copy_constructible<Result>::value) {
return cache[state];
}
无法编译。要解决这个问题,你可以写:
public class PassportStamp
{
[Key]
public int Id { get; set; }
[MaxLength(10, ErrorMessage = "BloggerName must be 10 characters or less"), MinLength(5)]
public string BloggerName { get; set; }
[Required]
public string Title { get; set; }
[NotMapped]
public string BlogCode
{
get
{
return Title.Substring(0, 1) + ":" + BloggerName.Substring(0, 1);
}
}
}
如果您仍然遇到问题,请发布有错误的MCVE。