VC6和模板错误

发布于 2024-08-04 05:35:47 字数 1448 浏览 9 评论 0原文

我正在重载运算符 <<为类实现类似流的接口:

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

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

模板版本无法编译,并显示“致命错误 C1001:内部编译器错误(编译器文件“msc1.cpp”,第 1794 行)”。非模板函数都可以正确编译。

这是由于 VC6 在处理模板时存在缺陷吗?有没有办法解决这个问题?

谢谢, Patrick

编辑:

完整的类是:

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() 用作流操纵器:

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

I am overloading operator << to implement a stream like interface for a class:

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

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

The template version fails to compile with "fatal error C1001: INTERNAL COMPILER ERROR (compiler file 'msc1.cpp', line 1794)". Non-template functions all compile correctly.

Is this due to VC6s deficiencies when handling templates and is there a way around this?

Thanks,
Patrick

EDIT :

the full class is:

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

The problem occurs with the function overload of operator << which is used to allow write() to be used as a stream manipulator:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

甚是思念 2024-08-11 05:35:47

对于旧的 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;
}

That overload of the template for function pointers surely is too much for good old Visual Studio 6.
As a workaround you could define a type for your manipulator and overload operator<< for that type.
Here's some code:

#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;
}
子栖 2024-08-11 05:35:47

这种错误看起来确实像是由 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 内的第二次查找只需要处理名为 printCAudit 成员。

The kind of error definitely looks like the kind of crashes caused by VC6's pre-previous-standard implementation of templates.

The best advice is of course to upgrade to either VC7.0, 7.1, 8.0, 9.0 or the beta of 10.
To compare that to Windows versions, it's still using Windows 98 when Me, 2000, XP, Vista and 7 are available.

Having said that, you can simplify the lookup a lot by a simple trick:

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

The hope here is that the first lookup of operator<< finds the single member template. The other operator<< candidates are non-members for other classes and built-ins. They should be unambiguously worse that this template. The second lookup inside your operator only needs to deal with CAudit members called print.

姜生凉生 2024-08-11 05:35:47
 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;
}
 template<typename T>
    CAudit& operator <<  (T data ) {
        audittext << data;
        return *this;
    }

EDIT:

#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;
}
〗斷ホ乔殘χμё〖 2024-08-11 05:35:47

问题似乎不在您发布的代码片段中。该程序运行良好:

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

您可以发布更多代码吗?

The problem does not seem to be in the code snippet you posted. This program works fine:

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

Could you post some more code?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文