0

クラスのインターフェイスのようなストリームを実装するために、演算子 << をオーバーロードしています。

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

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

テンプレート バージョンは、「致命的なエラー C1001: INTERNAL COMPILER ERROR (compiler file 'msc1.cpp', line 1794)」でコンパイルに失敗します。非テンプレート関数はすべて正しくコンパイルされます。

これは、テンプレートを処理する際の VC6 の欠陥によるものですか? これを回避する方法はありますか?

ありがとう、パトリック

編集 :

完全なクラスは次のとおりです。

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;
};

この問題は、write() をストリーム マニピュレータとして使用できるようにするために使用される operator << の関数オーバーロードで発生します。

CAudit audit
audit << "Billy" << write;
4

4 に答える 4

1

関数ポインターのテンプレートのオーバーロードは、確かに古き良き Visual Studio 6 には多すぎます。回避策として、マニピュレーターの型を定義し、その型の operator<< をオーバーロードできます。ここにいくつかのコードがあります:

#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;
}
于 2009-09-08T02:27:22.023 に答える
1

エラーの種類は、VC6 のテンプレートの以前の標準実装によって引き起こされた種類のクラッシュのように見えます。

もちろん、最善のアドバイスは、VC7.0、7.1、8.0、9.0、または 10 のベータ版にアップグレードすることです。これを Windows バージョンと比較すると、Me、2000、XP、Vista、および 7 が利用可能な場合でも、まだ Windows 98 を使用しています。

そうは言っても、簡単なトリックでルックアップを大幅に簡素化できます。

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<<候補は、他のクラスおよび組み込みの非メンバーです。このテンプレートよりも明らかに悪いはずです。内部の 2 番目のルックアップは、というメンバーoperatorを処理する必要があるだけです。CAuditprint

于 2009-09-07T11:44:54.620 に答える
0
 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;
}
于 2009-09-07T08:56:12.630 に答える
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;
}

もう少しコードを投稿できますか?

于 2009-09-07T09:31:27.177 に答える