C ++ مترجم قادر على العثور على وظيفة (مساحة ذات الصلة)

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

سؤال

وأنا أعمل في Visual Studio 2008 على C ++ الاحالة البرمجة. وقد زودنا مع الملفات التي تحدد التسلسل الهرمي مساحة الاسم التالي (الأسماء فقط من أجل هذا المنصب، وأنا أعلم "مساحة XYZ-NAMESPACE" لا لزوم لها):

(MAIN-NAMESPACE){

      a bunch of functions/classes I need to implement...

      (EXCEPTIONS-NAMESPACE){

            a bunch of exceptions
      }

      (POINTER-COLLECTIONS-NAMESPACE){

            Set and LinkedList classes, plus iterators
      }
}

ويتم تقسيم محتويات الرئيسي-NAMESPACE بين مجموعة من الملفات، ولسبب وأنا لا أفهم المشغل << لكل مجموعة وقائمة متصلة هو تماما خارج الرئيسي-NAMESPACE (ولكن ضمن مجموعة وقائمة متصلة في رأس ملف). وفيما يلي مجموعة النسخة:

template<typename T>
std::ostream& operator<<(std::ostream& os, 
                         const MAIN-NAMESPACE::POINTER-COLLECTIONS-NAMESPACE::Set<T>& set)

والآن وهنا المشكلة: لدي بنية البيانات التالية:

Set A
Set B
Set C
double num

ولقد تعرف أن يكون في فئة داخل MAIN-NAMESPACE. عندما أقوم بإنشاء مثيل من فئة، ومحاولة طباعة واحدة من مجموعات، ويقول لي ما يلي: خطأ C2679: ثنائي '<<': لم يتم العثور على المشغل الذي يأخذ المعامل الأيمن من نوع 'CONST MAIN-NAMESPACE :: POINTER-COLLECTIONS-NAMESPACE :: مجموعة' (أو لا يوجد تحويل مقبول)

ولكن، إذا كنت مجرد كتابة الوظيفة الرئيسية ()، وإنشاء مجموعة A، ملء عنه، واستخدام operator- يعمل.

وأي فكرة ما هي المشكلة؟ (ملاحظة: حاولت أي مزيج من استخدام وتشتمل على ما كنت أفكر فيه).

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

المحلول 2

وOK أنا أحسب ذلك. كان الحدس jpalecek حول هناك عامل آخر << في مساحة الاسم الصحيح القائم (على ما يبدو نسيت أن أعلق بها).

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

والحل هو إما إدراجه في MAIN-NAMESPACE (أنا الذي لا يسمح لل)، أو استيراده من مساحة الاسم العالمي مع "باستخدام :: المشغل <<".

نصائح أخرى

وغريب - على الرغم من وضع وظائف خالية المرتبطة بنوع إلى مساحة اسم مختلف هو ممارسة سيئة، والإعلانات مساحة العالمية هي دائما واضحة

.

والشيء الوحيد الذي يمكنني أن أفكر في ذلك الإعلان الذي يحمل نفس الاسم في MAIN-NAMESPACE أن الظل واحدة في مساحة الاسم العالمي - لا يوجد operator<<، ربما لنوع لا علاقة لها تماما، في MAIN-NAMESPACE؟ إذا كان الأمر كذلك، يجب تحديد ذلك بموجب إعلان using ::operator<< في MAIN-NAMESPACE. مثال:

namespace A
{
namespace B
{
  class C{};
}

}

void f(A::B::C*);

namespace A
{
  void f(int*); // try commenting
  using ::f; // these two lines
  void g()
  {
    B::C* c;
    f(c);
  }
}

وحاول استدعاء الدالة صراحة؟

::operator<<( cout, myObj );

وكما أشار SoaBox بها، محاولة يدعو بشكل صريح.

لمعلوماتك، إذا كنت ترغب في استدعاء دالة العالمية التي كانت مخبأة في مساحة الاسم الحالي تسبق وظيفة مع :: لتجاوز وظيفة المحلية واستدعاء الدالة العالمية.

<اقتباس فقرة>   

وحاول استدعاء الدالة صراحة؟

     

و:: المشغل << (cout، myObj)؛

نعم، هذا لا يعمل!

<اقتباس فقرة>   

وسوف محاولة للعثور على وظيفة و في   مساحة الاسم الحالي (في مكان   الدعوة) أو في مساحات إرفاق   من أنواع C1 و C2 (namespace1،   namespace2 :: namespace3)، ولكنها سوف   لا تحاول مساحات أخرى في   البحث.

لذلك دعونا نرى إذا حصلت على هذا الحق: سبب استدعاء المشغل << من الوظيفة الرئيسية () يعمل هو لأنني كنت في مساحة الاسم العالمي (كما كان المشغل <<). والسبب أنه فشل عند استدعاء من الصف الأول تنفيذها لأن الطبقة كانت في مساحة لا العالمي وكانت هناك متغيرات في أن أشار مترجم نحو مساحة الاسم العالمي.

طلب

موافق الناس لأمثلة محددة، لذلك هنا الجزء ذي الصلة من التعليمات البرمجية. // اخلاء المسؤولية: في حالة شخص سليم من وجهة نظري يوني يرى ذلك، واجه في ملف التقديم، وتقرر I نسخها أو شيء من هذا، رقم هاتفي الطالب 311670137

وهذا هو Set.h ملف الرأس:

   namespace MTM {//This is the MAIN-NAMESPACE

    namespace PointerCollections {

        (ITERATORS AND PREDICATE CLASSES)

        template<typename T>
        class Set {
        public:

        /////////////////////////////////
        // Definitions
        /////////////////////////////////

        private:

        /////////////////////////////////
        // Definitions
        /////////////////////////////////

        };


///////////////////////////////////////////////////////////////////////////////
// The implementation part. 
///////////////////////////////////////////////////////////////////////////////
      }
}
// operator<< - the same a Set::print(std::ostream& os,
//                                    const BinaryPredicate<T>& predicate) 
// function called with the 'predicate' parameter omitted
template<typename T>
std::ostream& operator<<(std::ostream& os, 
                         const MTM::PointerCollections::Set<T>& set){

    set.print(os);
    return os;
}

وهذا ما يعرف في ملف مختلف:

namespace MTM {
    using std::ostream;

    class Schedule {
    public:
      ///////////////////
      //Definitions, including: 
      ///////////////////
    void registerStation(string stationName);
    void reportRegisteredStations(std::ostream& outputStream) const;

    private:     //My database
               //All the classes Set recieves are defined elsewhere
        Set<RegisteredStation> places;
        Set<BusLine> busses;
        Set<TrainLine> trains;
        double tarifForBuses;
        double tarifForTrains;
    };

}

وهنا هو من رئيسية هي:

Schedule s();
s.registerStation("1");
s.reportRegisteredStations(cout);//This invokes the error. Definition follows:

ويعرف reportRegisteredStations على النحو التالي:

void Schedule::reportRegisteredStations(std::ostream& outputStream) const{

        outputStream<<places;
    }

وهذا يعمل بالنسبة لي

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

   namespace MTM {//This is the MAIN-NAMESPACE

    namespace PointerCollections {

        template<typename T>
        class Set {
        };


      }
}
template<typename T>
std::ostream& operator<<(std::ostream& os, 
                         const MTM::PointerCollections::Set<T>& set){

    return os;
}

namespace MTM {
    using std::ostream;
  using PointerCollections::Set;
    class Schedule {
    public:
      ///////////////////
      //Definitions, including: 
      ///////////////////
    void registerStation(string stationName);
    void reportRegisteredStations(std::ostream& outputStream) const;

    private:     //My database
               //All the classes Set recieves are defined elsewhere
        Set<int> places;
        Set<int> busses;
        Set<int> trains;
        double tarifForBuses;
        double tarifForTrains;
    };
void Schedule::reportRegisteredStations(std::ostream& outputStream) const{

        outputStream<<places;
    }

}

int main()
{
  MTM::Schedule s;
  s.reportRegisteredStations(std::cout);
}

<القوي> تصحيح : لويستند النص أدناه على تجربة مع العائلة ز ++ من المجمعين. بعد تعليق على الجواب لقد إعادة قراءة مستوى (التي تنص على أن ADL سيتم استخدامها خلال البحث عن اسم منتظم، والبحث عن اسم العادي أن تجد المشغل <<). لقد حاولت أيضا مع كومو مترجم (المترجم متوافقة مع معظم القياسية أعرف) ويتم العثور على رمز. يبدو كمشكلة مع g ++ (الإصدارات حاول 3.3، 4.1، 4.3).

الجواب الأصل:

والبحث عن Koening البحث. (من الناحية الفنية ADL: وسيطة البحث التابعة)

والجواب القصير هو أنه إذا كان لديك الطبقة التالية:

namespace test {
    class A {};
}

وينبغي تحديد المشغل تيار الإدراج على النحو التالي:

namespace test {
    std::ostream& operator<<( std::ostream&, A const & );
}
يجب أن تحدد

وظائف أو المشغلين في نفس مساحة واحدة من الحجج التي ما يلزم. (*)

وعندما يجد المترجم استدعاء دالة مثل:

namespace test2 {
   void g() {
      namespace1::class1 c1;
      namespace2::namespace3::class2 c2;
      f( c1, c2 );
   }
}

وسوف نحاول العثور على و وظيفة في مساحة الاسم الحالي (في مكان الدعوة) أو في مساحات إرفاق أنواع C1 و C2 (namespace1، namespace2 :: namespace3)، لكنه لن محاولة مساحات أخرى في البحث.

و(*) في هذه الحالة، هل تقتصر إلى حد كبير على المحك <م> مساحة الاسم، كما لا يسمح لك لإضافة وظيفة إلى مساحة الأمراض المنقولة جنسيا (فقط التخصصات قالب).

نهاية آخر الأصلي .

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

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