由于 C++11 标准导致的标头中的 QtGStreamer 编译时错误?
QtGStreamer compile-time error in header due to C++11 standard?
我正在尝试将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 相等性检查的模板参数是一个巨大的提示。
我遇到这个问题是因为我将RefPointer
s与常数NULL
进行比较,常数#define
d到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!
编译器尝试调用RefPointer
的operator==
函数,但发现它不适用于int
的X
参数(它只允许你传入指针(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 类型的指针的类,因此您必须将它们视为值而不是指针。