كيفية تكرار أكثر الأمراض المنقولة جنسيا::الخريطة الكاملة من السلاسل في C++
-
21-08-2019 - |
سؤال
لدي المشكلة التالية المتعلقة بالتكرار على مجموعة النقابي من سلاسل المعرفة باستخدام std::map
.
-- snip --
class something
{
//...
private:
std::map<std::string, std::string> table;
//...
}
في منشئ أنا ملء الجدول مع أزواج من سلسلة المفاتيح المرتبطة إلى سلسلة البيانات.في مكان آخر لدي طريقة toString
التي تقوم بإرجاع سلسلة كائن الذي يحتوي على جميع مفاتيح وما يرتبط بها من البيانات الواردة في الجدول الكائن(كما key=تنسيق البيانات).
std::string something::toString()
{
std::map<std::string, std::string>::iterator iter;
std::string* strToReturn = new std::string("");
for (iter = table.begin(); iter != table.end(); iter++) {
strToReturn->append(iter->first());
strToReturn->append('=');
strToRetunr->append(iter->second());
//....
}
//...
}
عندما أحاول تجميع أحصل على الخطأ التالي:
error: "error: no match for call to ‘(std::basic_string<char,
std::char_traits<char>, std::allocator<char> >) ()’".
هل يمكن لأحدكم أن يشرح لي ما هو مفقود ، ما أقوم به خطأ ؟ أنا فقط وجدت بعض النقاش حول مشكلة مشابهة في حالة hash_map
حيث يجب على المستخدم تحديد وظيفة التجزئة أن تكون قادرة على استخدام hash_map
مع std::string
الكائنات.يمكن أن يكون شيئا مماثلة أيضا في حالتي ؟
المحلول
المشكلة الرئيسية الخاصة بك هو أن يتم استدعاء أسلوب يسمى first()
في التكرار.ما كنت من المفترض القيام به هو استخدام خاصية تسمى first
:
...append(iter->first) rather than ...append(iter->first())
كمسألة من الطراز يجب أن لا تستخدم new
إلى إنشاء هذه السلسلة.
std::string something::toString()
{
std::map<std::string, std::string>::iterator iter;
std::string strToReturn; //This is no longer on the heap
for (iter = table.begin(); iter != table.end(); ++iter) {
strToReturn.append(iter->first); //Not a method call
strToReturn.append("=");
strToReturn.append(iter->second);
//....
// Make sure you don't modify table here or the iterators will not work as you expect
}
//...
return strToReturn;
}
تحرير: facildelembrar أشار (في التعليقات) التي في الحديث C++ يمكنك الآن كتابة حلقة
for (auto& item: table) {
...
}
نصائح أخرى
لا تكتب
toString()
الأسلوب.هذا ليس جافا.تنفيذ تيار مشغل للفئة الخاصة بك.تفضل باستخدام معيار خوارزميات أكثر من الكتابة الخاصة بك الحلقة.في هذه الحالة ،
std::for_each()
يوفر واجهة جميلة إلى ما تريد القيام به.إذا كنت يجب أن تستخدم حلقة لكن لا تنوي تغيير البيانات ، تفضل
const_iterator
أكثرiterator
.بهذه الطريقة, إذا كنت بالصدفه محاولة تغيير القيم المترجم سوف يحذرك.
ثم:
std::ostream& operator<<(std::ostream& str,something const& data)
{
data.print(str)
return str;
}
void something::print(std::ostream& str) const
{
std::for_each(table.begin(),table.end(),PrintData(str));
}
ثم عندما تريد طباعة فقط تيار وجوه:
int main()
{
something bob;
std::cout << bob;
}
إذا كنت فعلا في حاجة الى تمثيل سلسلة من وجوه, ثم يمكنك استخدام lexical_cast
.
int main()
{
something bob;
std::string rope = boost::lexical_cast<std::string>(bob);
}
التفاصيل التي تحتاج إلى أن تملأ.
class somthing
{
typedef std::map<std::string,std::string> DataMap;
struct PrintData
{
PrintData(std::ostream& str): m_str(str) {}
void operator()(DataMap::value_type const& data) const
{
m_str << data.first << "=" << data.second << "\n";
}
private: std::ostream& m_str;
};
DataMap table;
public:
void something::print(std::ostream& str);
};
وتغيير يدعو إلحاقي ليقول
...append(iter->first)
و
... append(iter->second)
وبالإضافة إلى ذلك، سطر
std::string* strToReturn = new std::string("");
ويخصص سلسلة على الكومة. إذا كنت تنوي فعلا للعودة مؤشر إلى هذه السلسلة المخصصة بشكل حيوي، يجب تغيير العودة إلى STD :: سلسلة *.
وبدلا من ذلك، إذا كنت لا تريد أن تقلق حول إدارة هذا الكائن على كومة، تغيير إعلان المحليين ل
std::string strToReturn("");
ووتغيير "إلحاقي" يدعو إلى استخدام بناء جملة مرجعية ...
strToReturn.append(...)
وبدلا من
strToReturn->append(...)
كن على علم بأن هذا بناء السلسلة على المكدس، ثم <م> نسخة م> عليه في متغير العودة. وهذا له آثار الأداء.
لاحظ أن نتيجة dereferencing والأمراض المنقولة جنسيا :: خريطة :: مكرر هي الأمراض المنقولة جنسيا :: زوج . قيم first
وsecond
ليست وظائف، فهي المتغيرات.
والتغيير:
iter->first()
إلى
iter->first
وكما سبق مع iter->second
.
وiter->first
وiter->second
والمتغيرات، وأنت تحاول أن تسميها وسائل.
استخدم:
std::map<std::string, std::string>::const_iterator
وبدلا من ذلك:
std::map<std::string, std::string>::iterator
وفي ج ++ 11 يمكنك استخدام
for ( auto iter : table ) {
key=iter->first();
value=iter->second();
}
آخر يستحق الأمثل هو c_str ( ) عضو في المحكمة الخاصة بلبنان سلسلة الطبقات التي عوائد ثابتة null إنهاء السلسلة التي يمكن تمريرها في كل مكان LPCTSTR, ه.ز., وظيفة مخصصة التي يتوقع LPCTSTR.على الرغم من أنني لم تتبع من خلال المدمر للتأكد من ذلك, وأظن أن السلسلة تبدو الدرجة بعد الذاكرة الذي يخلق نسخ.