كيفية تكرار أكثر الأمراض المنقولة جنسيا::الخريطة الكاملة من السلاسل في C++

StackOverflow https://stackoverflow.com/questions/1066677

سؤال

لدي المشكلة التالية المتعلقة بالتكرار على مجموعة النقابي من سلاسل المعرفة باستخدام 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) {
    ...
}

نصائح أخرى

  1. لا تكتب toString() الأسلوب.هذا ليس جافا.تنفيذ تيار مشغل للفئة الخاصة بك.

  2. تفضل باستخدام معيار خوارزميات أكثر من الكتابة الخاصة بك الحلقة.في هذه الحالة ، std::for_each() يوفر واجهة جميلة إلى ما تريد القيام به.

  3. إذا كنت يجب أن تستخدم حلقة لكن لا تنوي تغيير البيانات ، تفضل 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.على الرغم من أنني لم تتبع من خلال المدمر للتأكد من ذلك, وأظن أن السلسلة تبدو الدرجة بعد الذاكرة الذي يخلق نسخ.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top