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");
;与 a
、b
、c
.
类似
我有一个现有的 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");
;与 a
、b
、c
.