خطأ مع t :: iterator ، حيث قد تكون معلمة القالب t ناقلات أو قائمة

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

  •  03-10-2019
  •  | 
  •  

سؤال

أحاول كتابة وظيفة لطباعة تمثيل حاويات STL الشائعة (المتجه ، القائمة ، إلخ ..). أعطيت الوظيفة معلمة قالب T والتي ، على سبيل المثال ، قد تمثل المتجه. أواجه مشاكل في الحصول على مؤلف من النوع T.

vector<int> v(10, 0);
repr< vector<int> >(v);

...

template <typename T>
void repr(const T & v)
{
    cout << "[";
    if (!v.empty())
    {
        cout << ' ';
        T::iterator i;
        for (i = v.begin(); 
             i != v.end()-1;
             ++i)
        {
            cout << *i << ", ";
        }
        cout << *(++i) << ' ';
    }
    cout << "]\n";
}

...

brett@brett-laptop:~/Desktop/stl$ g++ -Wall main.cpp
main.cpp: In function ‘void repr(const T&)’:
main.cpp:13: error: expected ‘;’ before ‘i’
main.cpp:14: error: ‘i’ was not declared in this scope
main.cpp: In function ‘void repr(const T&) [with T = std::vector<int, std::allocator<int> >]’:
main.cpp:33:   instantiated from here
main.cpp:13: error: dependent-name ‘T::iterator’ is parsed as a non-type, but instantiation yields a type
main.cpp:13: note: say ‘typename T::iterator’ if a type is meant

حاولت "Typename t :: iterator" كما اقترح المترجم ، ولكن حصلت فقط على خطأ أكثر خفية.

تحرير: شكرا للمساعدة يا شباب! إليك نسخة عمل لأي شخص يريد استخدام هذه الوظيفة:

template <typename T>
void repr(const T & v)
{
    cout << "[";
    if (!v.empty())
    {
        cout << ' ';
        typename T::const_iterator i;
        for (i = v.begin(); 
             i != v.end();
             ++i)
        {
            if (i != v.begin())
            {
                cout << ", ";
            }
            cout << *i;
        }
        cout << ' ';
    }
    cout << "]\n";
}
هل كانت مفيدة؟

المحلول

انت تحتاج typename لإخبار المترجم بذلك ::iterator من المفترض أن يكون نوعا. لا يعرف المترجم أنه نوع لأنه لا يعرف ما هو حتى تقوم بتسهيل القالب. يمكن أن يشير أيضًا إلى بعض أعضاء البيانات الثابتة ، على سبيل المثال. هذا هو الخطأ الأول لك.

خطأك الثاني هو ذلك v هو إشارة إلى-مقدار ثابت. لذلك ، بدلا من ::iterator عليك أن تستخدم ::const_iterator. لا يمكنك أن تطلب حاوية ثابتة لمؤلف غير مؤلف.

نصائح أخرى

يتغيرون T::iterator i; إلى typename T::const_iterator i; لان ::iterator من النوع T و v هو const &.

قبل نوع التابع المؤهل ، تحتاج typename. بدون typename, ، هناك قاعدة تحليل C ++ التي تنص على أنه يجب تحليل الأسماء المعتمدة المؤهلة non-types حتى لو كان يؤدي إلى خطأ في بناء الجملة.

typename ينص على أن الاسم التالي يجب أن يعامل كنوع. خلاف ذلك ، يتم تفسير الأسماء للإشارة إلى غير الأنواع.

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