سؤال

أنا مشغل التحميل الزائد << لتنفيذ دفق مثل واجهة لفئة:

template<typename T>
CAudit& operator <<  ( const T& data ) {
    audittext << data;
    return *this;
}

CAudit& operator << ( LPCSTR data ) {
    audittext << data;
    return *this;
}

فشل إصدار القالب في التجميع مع "خطأ فادح C1001: خطأ في المترجم الداخلي (ملف البرمجة" msc1.cpp "، السطر 1794)". وظائف غير المسلمين جميعها تجمع بشكل صحيح.

هل هذا بسبب أوجه القصور VC6S عند التعامل مع القوالب وهل هناك طريقة للتغلب على هذا؟

شكرا ، باتريك

تعديل :

الفصل الكامل هو:

class CAudit
{
public:    
/* TODO_DEBUG : doesn't build! 
template<typename T>
CAudit& operator <<  ( const T& data ) {
    audittext << data;
    return *this;
}*/

~CAudit() { write(); }//If anything available to audit write it here

CAudit& operator << ( LPCSTR data ) {
    audittext << data;
    return *this;
}

//overload the << operator to allow function ptrs on rhs, allows "audit << data << CAudit::write;"
CAudit& operator << (CAudit & (*func)(CAudit &))
{
    return func(*this);
}

void write() {
}

//write() is a manipulator type func, "audit << data << CAudit::write;" will call this function
static CAudit& write(CAudit& audit) { 
    audit.write();
    return audit; 
}

private:
std::stringstream audittext;
};

تحدث المشكلة مع استخدام الوظيفة الزائدة للمشغل << والتي تستخدم للسماح باستخدام الكتابة () كمناور دفق:

CAudit audit
audit << "Billy" << write;
هل كانت مفيدة؟

المحلول

هذا الحمل الزائد من القالب الخاص بتأسيس الوظائف هو بالتأكيد أكثر من اللازم بالنسبة إلى Visual Studio القديم الجيد 6. بصفتك حلًا ، يمكنك تحديد نوع لمشغل الحمل الزائد << لهذا النوع. إليك بعض التعليمات البرمجية:

#include "stdafx.h"
#include <string>
#include <iostream>
#include <sstream>
#include <windows.h>

class CAudit {

    std::ostringstream audittext;
    void do_write() {}

public:
    ~CAudit() { do_write(); } 

    // types for manipulators
    struct Twrite {};

    // manipulators
    static Twrite write;

    // implementations of <<
    template<typename T>
        CAudit& operator <<  ( const T& data ) {
        audittext << data;
        return *this;
    }

    CAudit& operator <<  ( LPCSTR data ) {
        audittext << data;
        return *this;
    }

    CAudit& operator <<  ( Twrite& ) {
        do_write();
        return *this;
    }
};

// static member initialization
CAudit::Twrite CAudit::write;



int main(int argc, char* argv[])
{
    CAudit a;
    int i = 123;
    const char * s = "abc";

    a << i << s << CAudit::write;

    return 0;
}

نصائح أخرى

يبدو هذا النوع من الخطأ بالتأكيد نوعًا من الحوادث الناجمة عن تنفيذ قوالب محددة مسبقًا لـ VC6.

أفضل نصيحة هي بالطبع الترقية إلى VC7.0 أو 7.1 و 8.0 و 9.0 أو بيتا من 10. لمقارنة ذلك بإصدارات Windows ، لا يزال يستخدم Windows 98 عندما تتوفر Me و 2000 و XP و Vista و 7.

بعد قولي هذا ، يمكنك تبسيط البحث كثيرًا عن طريق خدعة بسيطة:

class CAudit {
    template<typename T>
    CAudit& operator<<(T const& t) {
        this->print(t);
        return *this;
    }
private:
    void print(int);
    void print(LPCSTR);
    void print(CAudit & (*func)(CAudit &));
    template<typename T> print(T const&);
};

الأمل هنا هو أن أول بحث operator<< يجد قالب عضو واحد. الأخرى operator<< المرشحون غير أعضاء لفصول أخرى وبيانات. يجب أن تكون أسوأ بشكل لا لبس فيه أن هذا القالب. البحث الثاني داخل الخاص بك operator يحتاج فقط للتعامل مع CAudit دعا الأعضاء print.

 template<typename T>
    CAudit& operator <<  (T data ) {
        audittext << data;
        return *this;
    }

تعديل:

#include <iostream>
using namespace std;

class CAudit{
public:
    CAudit(){}

    template< typename T >
    CAudit &operator<<(T arg);
    CAudit &operator<<(char s);
};

template< typename T>
void oldLog(T arg){
  cout << arg;
}

template< typename T >
CAudit &CAudit::operator<<(T arg){
    oldLog( arg );
    return *this;
}
CAudit &CAudit::operator<<(char arg){
    oldLog( arg );
    return *this;
}
int main(){

    CAudit e;
    e << "Hello";
    e << 'T';

 return 0;
}

لا يبدو أن المشكلة في مقتطف الرمز الذي نشرته. هذا البرنامج يعمل بشكل جيد:

#include "stdafx.h"
#include <string>
#include <iostream>
#include <sstream>
#include <windows.h>

class CAudit {

std::ostringstream audittext;

public:
std::string getAuditText() const { return audittext.str(); }

template<typename T>
    CAudit& operator <<  ( const T& data ) {
    audittext << data;
    return *this;
}


CAudit& operator <<  ( int data ) {
    audittext << data;
    return *this;
}

CAudit& operator << ( LPCSTR data ) {
audittext << data;
return *this;
}
};


int main(int argc, char* argv[])
{
CAudit a;
int i = 123;
const char * s = "abc";

a << i;
a << s;

std::cout << "audittext is: '" << a.getAuditText() << "'\n";
return 0;
}

هل يمكنك نشر المزيد من التعليمات البرمجية؟

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