我有以下任务
开发一个名为 Translator 的类,它允许保存双语单词对,然后使用已添加的单词对将单词从一种语言翻译为另一种语言:
class Translator {
public:
void Add(string_view source, string_view target);
string_view TranslateForward(string_view source) const;
string_view TranslateBackward(string_view target) const;;
private:
//
};
更具体地说,类型为
t
的对象 Translator
应支持以下操作:
使用默认构造函数创建。在这种情况下,翻译库是空的。
添加双语对:
t.Add(source, target)
。在此调用之后,假设语言 1 中的单词 source
对应于语言 2 中的单词 target
。传递给 Add
方法的字符串可能会在 t
对象之前被销毁。
从语言 1 到语言 2 的翻译:
t.TranslateForward(source)
。如果之前对某个字符串 t.Add(source_copy, target)
进行过调用 target
并且字符串 source_copy
等于 source
(或相同),则应返回 target
。如果没有这样的调用,它应该返回一个空字符串。如果有多个此类调用,则最后一个调用应返回 target
。
从语言 2 到语言 1 的翻译:
t.TranslateBackward(target)
。如果之前对某个字符串 t.Add(source, target_copy)
进行过调用 source
并且字符串 target_copy
等于 target
(或相同),则应返回 source
。如果没有这样的调用,它应该返回一个空字符串。如果有多个此类调用,则最后一个调用应返回 source
。
限制:
Translator
类实例中的存储次数不得超过一次。如果违反此限制,您将收到“超出内存限制”错误。基本上我尝试了以下简单的想法:
#include <string_view>
#include <string>
#include <map>
using namespace std;
class Translator {
public:
void Add(string_view source, string_view target){
forward[source] = target;
backward[target] = source;
};
string_view TranslateForward(string_view source) const{
if(forward.count(source) == 0){
return string_view("");
}
return forward.at(source);
};
string_view TranslateBackward(string_view target) const{
if(backward.count(target) == 0){
return string_view("");
}
return backward.at(target);
};
private:
map<string_view,string_view> forward;
map<string_view,string_view> backward;
};
我用简单的案例进行了测试:
int main(){
Translator translator;
translator.Add(string("okno"), string("window"));
translator.Add(string("stol"), string("table"));
}
而且效果很好。但在隐藏测试中我得到了
TranslateForward() returned wrong data for temporary string (Time used: 1.78/5.00, preprocess time used: 0/None, memory used: 155656192/268435456.)
。看来我错过了一些边缘情况。
我想念什么(一般来说)?
错误的关键是“临时字符串”。为什么要在地图中存储 string_views ?实际的字符串存储在哪里?调用者字符串结束其生命周期是什么?
std::string_view
只是一个视图。它不拥有数据。它可以让您查看其他对象的数据。如果该其他对象不再存在,您将无法再查看它。
即使在您的示例中,实际字符串也是临时字符串,在完整表达式之后不再存在:
int main(){
Translator translator;
translator.Add(string("okno"), string("window"));
translator.Add(string("stol"), string("table"));
// already here the string_views in the map point to
// strings that no longer exist
}
将字符串存储在地图中,而不仅仅是视图中。