【问题标题】:QtGStreamer compile-time error in header due to C++11 standard?由于 C++11 标准,标头中的 QtGStreamer 编译时错误?
【发布时间】:2016-12-13 14:27:17
【问题描述】:

我正在尝试将 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);
}

其他人遇到了我收到的错误消息here

qt5gstreamer\qglib\refpointer.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 源代码中看到的 here (该版本的标头与我在系统上使用的版本相同。)

问: 鉴于上述情况,我的代码是否有问题?可以帮助 QtGstreamer 解决问题的东西;还是我只是为 C++ 标准的早期版本编译更好?

【问题讨论】:

    标签: c++ qt compiler-errors gstreamer


    【解决方案1】:

    事实证明,我的编译器并没有指出我遇到的问题的实际起源。 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*) 或其他 RefPointers.)

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

    if(ptr.isNull())
    

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

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

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

    【讨论】:

    • 这是您应该用nullptr 替换对NULL 的任何检查的主要原因。那会让你正确地理解错误。您唯一应该检查是否为空的时间是指针类型。即使RefPointer 包装了一个指针,它也不是指针类型。指针类型是 T*,例如 int*char*RefPointer*
    • 是的,我最终弄清楚了答案中写的关于RefPointer(它不是指针类型)的事实。感谢您提供有关nullptr 的提示;我一定会在将来使用它。奇怪的是RefPointer 的语义经常类似于实际指针,但各种“陷阱”不起作用。例如,要在包装的原始类型上调用函数,您必须使用-&gt;(也有一个重载运算符)。有趣...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-24
    • 1970-01-01
    • 2019-12-16
    • 1970-01-01
    相关资源
    最近更新 更多