MSVC2013 和 MingW 之间的差异导致最令人烦恼的解析问题

Differences between MSVC2013 and MingW lead to most vexing parse issue

我有一个现有的 C++ 和 Qt 程序,可以在 MSVC 下正常构建,但无法使用 MinGW 构建。

在 MinGW 下,我遇到很多语法错误,例如:

Redefinition of 'QString foobar'

我已将问题提取到最小工作示例中:

//main.cpp
#include <QString>
#include <iostream>

using namespace std;

class MyClass {

public:
    MyClass(const QString &foo, const QString &bar, const QString baz)
        : foo_(foo), bar_(bar), baz_(baz) {}

    QString foo_;
    QString bar_;
    QString baz_;
};

int main(int argc, char **argv) {

    QString foo = QString("foo");
    QString bar = QString("bar");
    QString baz = QString("baz");

    MyClass my(foo, bar, baz);

    QString a = QString(foo);
    QString b = QString(bar);
    QString c = QString(baz);

    MyClass my2(a,b,c);
    MyClass my3(QString(foo), QString(bar), QString(baz));
    //MyClass my4(QString(foo), QString(bar), QString(foo)); //redefinition error

    return 0;
}

给出错误:

main.cpp:31: error: C2086: 'QString foo' : redefinition

正如评论中指出的那样,我的问题是由称为 "most vexing parse" 的解析问题引起的。有了这些知识,我进一步完善了我的问题,发现 MSVC 和 MinGW 之间存在以下差异。以下代码行在 MSVC2013 下编译但不在 MinGW 下:

MyClass my5(QString(foo), QString(bar), QString(foo), Foo::Foobar(5));

似乎添加 "Foo::Foobar(5)" 导致 MSVC 将此行视为变量声明,但 MinGW 仍将其视为函数声明。

我的问题是,我可以通过 GCC 中的一些编译标志来解决这个问题,还是我必须重构我的整个项目来避免最棘手的解析问题。

此代码将是一个函数声明:

MyClass my4(QString(foo), QString(bar), QString(foo));

因为它符合函数的语法规范。查找 "most vexing parse" 了解更多信息。错误是因为函数声明不能​​有两个具有相同标识符的参数。每当语句以 T name( U( 开头时,这是可能的

MyClass my4(QString(foo), QString(bar), QString(foo), Foo::Foobar(5)); 的错误可能是 gcc 编译器错误,它让我想起了

在这种情况下要避免此问题,请避免冗余转换:

MyClass my4(foo, bar, foo);

或者您可以养成使用列表初始化的习惯:

MyClass my4{ foo, bar, foo };

请注意,您在代码的前面也有几个冗余转换;例如QString foo = QString("foo"); 可以是 QString foo("foo");;与 abc.

类似