سؤال

لقد واجهت مشكلة غريبة. يستنسخ الكود المبسط التالي المشكلة في MSVC 2010:

template <typename T>
struct dummy
{
    static T foo(void) { return T(); }
};

int main(void)
{
    typedef dummy<bool> dummy_type;
    auto x = []{ bool b = dummy_type::foo(); };
    // auto x = []{ bool b = dummy<bool>::foo(); }; // works
}

ال typedef لقد ابتكرت محليًا في الوظيفة لا يبدو مرئيًا في Lambda. إذا استبدلت typedef مع النوع الفعلي ، يعمل كما هو متوقع.

فيما يلي بعض حالات الاختبار الأخرى:

// crashes the compiler, credit to Tarydon
int main(void)
{
    struct dummy {};

    auto x = []{ dummy d; };
}

// works as expected
int main(void)
{
    typedef int integer;

    auto x = []{ integer i = 0; };
}

ليس لدي G ++ متاح لاختباره الآن. هل هذه قاعدة غريبة في C ++ 0x ، أم مجرد خطأ في المترجم؟

من النتائج أعلاه ، أنا أميل نحو علة. على الرغم من أن الحادث هو بالتأكيد خطأ.


الآن ، لقد قدمت اثنين تقارير الأخطاء.

يجب أن تجمع جميع قصاصات الكود أعلاه. يتعلق الخطأ باستخدام دقة النطاق على النطاقات المحددة محليًا. (رصدت من قبل dvide.)

وعلاقة الحادث لها علاقة بـ ... من يدري. قون


تحديث

بحسب ال تقارير الأخطاء, ، كلاهما تم إصلاحهما للإصدار التالي من Visual Studio 2010. (على الرغم من أن هذا لا يبدو هو الحال ؛ VS11 ربما.)

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

المحلول

من N3000 ، 5.1.2/6 ،

ينتج عن المجموعة المركبة في Lambda-Expression جسم الوظيفة (8.4) لمشغل استدعاء الوظيفة ، ولكن لأغراض البحث عن الاسم (3.4) ، ... يتم النظر في المجموعة المركبة في سياق التعبير عن Lambda.

ليس من المستغرب أن يكون النوع المحلي مرئيًا.

نصائح أخرى

لا يمكن اكتشاف التعدادات المحلية للوظائف بواسطة Lambdas أيضًا.

int main()
{   
    enum E {A, B, C};   
    auto x = [](){ int a = A; }; 
    //auto y = [](){ E a = A; }; // this will crash the compiler
}

خطأ C3493: "A" لا يمكن التقاطه ضمنيًا لأنه لم يتم تحديد وضع الالتقاط الافتراضي

ما يلي هو ويلاح ، والمشاكل-رغم ذلك.

int main()
{   
    enum E {A, B, C};   
    auto x = [=](){ int a = A; };
    // typedef E F; 
    // auto y = [=](){ F a = A; }; // this compiles ok
}

هذه ليست حقًا إجابة على سؤالك ، ولكن فقط استكشاف المشكلة. كنت أتساءل عما إذا كان لدى المترجم مشاكل في التعامل معها الأنواع أعلن في نطاق مغلق ، لذلك جربت هذا:

#include <iostream>

template <typename Func>
void do_test(Func pFunc) {
}

template <typename T>
void test_trait(void) {
   class Something { public: int foo; };

   do_test ([] (T pX) {
      Something A; A.foo = 12;
   });
}

int main(void) {
    test_trait<int> ();
}

هنا ، أحاول فقط إنشاء نوع محلي في النطاق المرفق واستخدامه من داخل وظيفة Lambda. لا يقتصر الأمر على عدم تجميع هذا (مع Visual Studio 2010 ، Beta 2) ولكنه يعطل في الواقع المترجم بخطأ داخلي C1001.

لقد قدمت تقريرين خطأ.

سنرى كيف ستسير الأمور. قون


تحديث

تم تمييز كلا الحشيقين على أنهما ثابتان:

نحن نقدر ملاحظاتك. وقد شوهد هذا الخطأ من قبلنا من قبل وقد إصلاحه في الإصدار التالي. شكرا لك على استخدام المنتج.

شكرًا،
Ulzii Luvsanbat
فريق Windows C ++

لذلك هناك نذهب.

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