在尝试使用QDatastream序列化自定义类的QList时,出现C2679错误 [英] Error C2679 while trying to serialize QList of custom class with QDatastream

查看:4623
本文介绍了在尝试使用QDatastream序列化自定义类的QList时,出现C2679错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义类 Foo

  class Foo 
{
public:
// getters和setters
// ...
private:
QString string;
QStringList list;
int number;
}

Foo 已按预期工作:

  QDataStream& operator<<(QDataStream& stream,const Foo& foo)
{
stream<< foo.getString()<<< foo.getList()<< foo.getNumber();
return stream;
}

但是当我试图序列化 QList< Foo> ,我收到了

 错误C2679:binary'<类型为const Foo的右手操作符

,它指向相应的Qt代码(qdatastream。 h):

  template< typename T> 
QDataStream&运算符<<(QDataStream& s,const QList< T>& l)
{
s& quint32(l.size());
for(int i = 0; i< l.size(); ++ i)
s< l.at(i); //< --- compiler error here
return s;
}

我知道 QList< T& )返回 const T& ,但我不知道为什么它不能在这里编译。请指出我的错误,我想知道如何解决这个问题。此外,如果我错过了必要的代码部分,请让我知道。非常感谢!



[编辑]:
作为参考,我的环境是Qt 4.8.5与MSVC2010 / Win 7,使用Qt创建者。



此外,这是我如何序列化 QList< Foo>

  QFile文件(file.dat); 
file.open(QIODevice :: ReadWrite);
QDataStream out(& file);
out.setVersion(QDataStream :: Qt_4_8);

out<< fooList; //这是QList< Foo>它不是一个指针
// ^^^^^^^^^^编译器错误发生时,这行添加

[最后编辑]:



我终于知道发生了什么:



我定义的序列化 Foo 的运算符重载写在 seperate .cpp 档案,其中

  QDataStream& operator<<(QDataStream& stream,const Foo& ; foo)
{
stream<< foo.getString()<<< foo.getList()<< foo.getNumber
return stream;
}

内部 foo.cpp 可以编译上述代码,但现在我意识到它永远不会被使用! / p>

QList< Foo> 的序列化在另一个文件 notFoo.cpp ,这是一个更大的类



当我编译 notFoo.cpp 时,只有头文件中的定义和方法 qdatastream .h ,因此会出现错误C2679 ,其中:

  template< typename T> 
QDataStream&运算符<<(QDataStream& s,const QList< T>& l)
{
s& quint32(l.size());
for(int i = 0; i< l.size(); ++ i)
s< l.at(i); //< ---编译器错误here
return s;
}

这表明编译器不知道如何进一步serialze类型 Foo

  binary'<类型const Foo的右手操作数

这意味着< ; <<找不到(因为我在另一个 .cpp 文件中定义它)



将序列化方法从 Foo.cpp 移动到 notFoo.cpp 后,代码可以



[结束]:

Foo.h 中找到函数签名,因为我在 Foo.cpp 中定义了流运算符inline。

解决方案

您需要在声明序列化类型的同一标题中声明流操作符:

  // Foo.h 
#include< QString>
#include< QDataStream>

class Foo
{
public:
// getters和setters
// ...
private:
QString串;
QStringList list;
int number;
};

QDataStream& operator<<(QDataStream& stream,const Foo& foo);

通常,运算符的实现 code> Foo ,但它可以在任何.cpp文件,真的:

  // Foo.cpp 

Foo :: Foo(){
...
}

...
$ b b QDataStream& operator<<(QDataStream& stream,const Foo& foo)
{
stream<< foo.getString()<< foo.getList() ; foo.getNumber();
return stream;
}


I got a custom class Foo:

class Foo
{
public:
    // getters and setters
    // ...
private:
    QString string;
    QStringList list;
    int number;
}

The serialization of Foo has worked as expected:

QDataStream &operator<<(QDataStream &stream, const Foo &foo)
{
    stream<<foo.getString()<<foo.getList()<<foo.getNumber();
    return stream;
}

but when I attempted to serialize QList<Foo>, I got

error C2679: binary '<<' : no operator found which takes a right-hand operand of type "const Foo"

which directed to the corresponding Qt code (qdatastream.h):

template <typename T>
QDataStream& operator<<(QDataStream& s, const QList<T>& l)
{
    s << quint32(l.size());
    for (int i = 0; i < l.size(); ++i)
        s << l.at(i); // <--- compiler error here
    return s;
}

I know QList<T>::at() returns const T &, but I have no idea why it should fail to compile here. Please point out my error, I'd like to know how to fix this. Also, if I miss the necessary parts of code please do let me know. Thanks!

[Edit]: For reference, my environment is Qt 4.8.5 with MSVC2010/ Win 7 and I am using Qt creator.

Besides, this is how I serialize QList<Foo>:

QFile file("file.dat");
file.open(QIODevice::ReadWrite);
QDataStream out(&file);
out.setVersion(QDataStream::Qt_4_8);

out<<fooList; // It's the instant of QList<Foo> and it's not a pointer
//^^^^^^^^^^ compiler errors occurs as this line is added

[Last Edit]:

I finally figure out what's going on:

The operator overload that I defined to serialize Foo is written in a seperate .cpp file, where

QDataStream &operator<<(QDataStream &stream, const Foo &foo)
{
    stream<<foo.getString()<<foo.getList()<<foo.getNumber();
    return stream;
}

is inside foo.cpp.

The above code can be compiled but now I realize that it will never be used!

The serialization of QList<Foo> is implemented in another file notFoo.cpp, which is a "bigger class".

As I compile notFoo.cpp, only the definition and methods inside the header qdatastream.h could be found hence the error C2679 comes out, where:

template <typename T>
QDataStream& operator<<(QDataStream& s, const QList<T>& l)
{
    s << quint32(l.size());
    for (int i = 0; i < l.size(); ++i)
        s << l.at(i); // <--- compiler error here
    return s;
}

It shows that compiler doesn't know how to further serialze type Foo.

binary '<<' : no operator found which takes a right-hand operand of type "const Foo"

which means << of s << l.at(i); is not found (since I defined it in another .cpp file)

After I move the serialization method from Foo.cpp to notFoo.cpp, the code can finally be compiled.

[Conclusion]:

The compiler didn't find the function signature in the Foo.h since I define the stream operator inline within Foo.cpp.

解决方案

You need to declare the stream operator in the same header where you declare the serialized type:

// Foo.h
#include <QString>
#include <QDataStream>

class Foo
{
public:
    // getters and setters
    // ...
private:
    QString string;
    QStringList list;
    int number;
};

QDataStream &operator<<(QDataStream &stream, const Foo &foo);

Usually, the operator's implementation will be in the file where you implement Foo, but it could be in any .cpp file, really:

// Foo.cpp

Foo::Foo() {
  ...
}

...

QDataStream &operator<<(QDataStream &stream, const Foo &foo)
{
    stream<<foo.getString()<<foo.getList()<<foo.getNumber();
    return stream;
}

这篇关于在尝试使用QDatastream序列化自定义类的QList时,出现C2679错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆