سؤال

انظر إلى الرمز البسيط التالي:

#include <iostream>
#include <string>
using namespace std;

int main()
{
    string s("1234567890");
    string::iterator i1 = s.begin();
    string::iterator i2 = s.begin();
    string s1, s2;
    s1.append(i1, ++i1);
    s2.append(++i2, s.end());

    cout << s1 << endl;
    cout << s2 << endl;
}

ماذا تتوقع أن يكون الناتج؟

هل، مثلي، نتوقع أن تكون:

1
234567890

خاطئ - ظلم - يظلم! أنه:

234567890

أي السلسلة الأولى فارغة.

طبقات أن المشغل زيادة البادئة مشكلة مع المحامي. أم هل فاتني شيء؟

هل كانت مفيدة؟

المحلول

ليس خطأ.

الترتيب الذي الحجج

s1.append(i1, ++i1);

يتم تقييمها غير محددة بواسطة المعيار. المحول البرمجي مجاني لاستخدام أي طلب يختاره. في هذه الحالة، يقيم الحجة الثانية (++i1) قبل الأول (i1) وتحدد مجموعة فارغة لنسخ.

نصائح أخرى

أنت تفتقد شيئا ما: هذا حقا لا علاقة له بالمقتطفات. يتم تقييم النظام الذي يتم فيه تقييم الحجج الوظيفة غير محددة. على هذا النحو: append(i1, ++i1); سيعتمد على سلوك غير محدد، بغض النظر عن نوع i1. وبعد فقط على سبيل المثال، إعطاء شيء أكثر بساطة مثل:

void print(int a, int b) { 
    std::cout << a << " " << b << "\n";
}

int main() { 
    int a =0;
    print(a, ++a);
    return 0;
}

يمكن أن يكون الإخراج الخاص بك بشكل معقول تماما "0 1" يبدو أنك تتوقع، ولكن يمكن أن يكون أيضا بشكل معقول أيضا: "1 1". نظرا لأن هذا غير محدد، فقد يتغير ذلك من إصدار واحد من المحول البرمجي إلى التالي، أو حتى مع نفس المحول البرمجي عند تغيير الأعلام، أو (من الناحية النظرية) قد تختلف اعتمادا على مرحلة القمر ...

تطبيقات C ++ مجانية لتقييم الحجج بأي ترتيب. في هذه الحالة، يتم تقييم IF ++ I1 أولا، ستحصل على سلسلة فارغة.

لا يحدد المعيار C ++ أي شيء حول الترتيب الذي يتم فيه تقييم وسيطات الوظائف، مما يجعله تنفيذه يعتمد. يتطلب C ++ أن يتم تقييم الوسائط الوظيفة بالكامل (وجميع الآثار الجانبية المنشورة) قبل الدخول إلى الوظيفة، ولكن التنفيذ مجاني لتقييم الحجج بأي ترتيب

في حالتك i++ حصلت على تقييمها قبل إجراء كل من المعلمات نفسها، مما يؤدي إلى سلسلة فارغة.

مزيد من المعلومات حول هذا السلوك هنا على شركات newsgroup.

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