由于 C++11 标准导致的标头中的 QtGStreamer 编译时错误?

QtGStreamer compile-time error in header due to C++11 standard?

本文关键字:QtGStreamer 编译时错误 标准 由于 C++11      更新时间:2023-10-16

我正在尝试将QtGStreamer与MS Visual Studio 2015的C++编译器一起使用,该编译器默认为C++11标准(或多或少)。

标头 refpointer.h 包含以下内容:

template <class T, class X>
struct RefPointerEqualityCheck<T, X*>
{
static inline bool check(const RefPointer<T> & self, X* const & other)
{
return self.m_class ? self.m_class->m_object == other : !other;
}
};

。稍后在 refpointer.h 中,我们有以下内容:

template <class T>
template <class X>
bool RefPointer<T>::operator==(const X & other) const
{
return Private::RefPointerEqualityCheck<T, X>::check(*this, other);
}
template <class T>
template <class X>
bool RefPointer<T>::operator!=(const X & other) const
{
return !Private::RefPointerEqualityCheck<T, X>::check(*this, other);
}

其他人遇到了我在这里收到的错误消息:

qt5gstreamerqglibrefpointer.h(280): error C2039: 'check': is not a member of 'QGlib::Private::RefPointerEqualityCheck<T,X>'
with
[
T=QGst::BufferList,
X=int
]

QtGStreamer的主要贡献者之一回答如下:

嗯,看起来代码需要一些添加来支持 C++11 空。尝试删除任何启用 C++11 的编译器标志 功能(包括QTGSTREAMER_FLAGS如果您使用的是 cMake)和 看看会发生什么。另外,如果您打开错误报告会很好 关于这个。

两件事:

(1)如果可以修复标头(并可能提交补丁),我想避免放弃C++11标准支持;和

(2)我什至不确定MSVC++ 15是否可以选择返回到早期的标准版本(我在谷歌搜索时不容易找到它)。

与编译器消息所说的相反,未经训练的眼睛似乎check确实被定义为QGlib::Private::RefPointerEqualityCheck的成员,正如您在QtGStreamer源代码中看到的那样(该版本的标头与我在系统上使用的标头相同。

问:鉴于上述情况,我的代码是否有问题;可以为QtGstreamer提供一些问题来解决问题;还是我只是为C++标准的早期版本进行编译更好?

事实证明,我的编译器并没有指出我遇到的问题的实际来源。RefPointer 相等性检查的模板参数是一个巨大的提示。

我遇到这个问题是因为我将RefPointers与常数NULL进行比较,常数#defined到0(编译成int)。

因此,当执行以下操作时:

BufferListPtr buf; //An instance of RefPointer
//I thought that BufferListPtr was equivalent to `QGst::Buffer*` but apparently it has some overloaded operators, which is the source of our problem!
if(buf == NULL) //Compile-time error!

编译器尝试调用RefPointeroperator==函数,但发现它不适用于intX参数(它只允许你传入指针(X*)或其他RefPointer)。

因此,您必须浏览QtGstreamer代码并找到将RefPointer实例与==!=NULL进行比较的所有时间,并按如下方式修复它们:

if(ptr.isNull())

要记住的是,所有 RefPointer 实例都是,而不是指针。如果你来自视觉C++世界(像我一样),并且你希望,比如说,LPCSTR一个简单的宏,为CSTR添加*,不要与QtGstreamer中的Ptr类和RefPointer做的事情混为一谈!声明一个RefPointer(例如,ElementPtr)实际上会立即在堆栈上分配该类的实例,因此将其与 NULL 进行比较是没有意义的。

但是你可以调用它isNull()以查看它是否为 NULL,因为如果你在堆栈上分配它并且你没有做一些奇怪的事情,比如声明一个ElementPtr*,那么这个类将始终被初始化。

总之,RefPointer及其所有子类,包括以Ptr结尾的 QtGstreamer 对象类型,只是一个封装指向原始 C 类型的指针的类,因此您必须将它们视为值而不是指针。