Visual Studio 2017:linux项目中的模糊符号size_t

vla*_*don 5 c++ visual-studio-2017

在Visual Studio 2017中创建Linux项目并插入using namespace std;源代码时,如下所示:

#include <iostream>
#include <string>

using namespace std;

int main()
{
    size_t i = 1;
    string s = to_string(i);
    cout << i << s << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

VS强调size_t并说这是一个模糊的符号.VS pic 1

如果我按下F12(Go to definition),它会为我提供两个定义位置:

从 stddef.h

(C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\Linux\include\usr\include\x86_64-linux-gnu\5\include\stddef.h):

// ...
namespace std
{
  typedef __SIZE_TYPE__     size_t;
// ...
Run Code Online (Sandbox Code Playgroud)

和 c++config.h

(C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\Linux\include\usr\include\x86_64-linux-gnu\c++\5\bits\c++config.h):

// ...
#if !(defined (__GNUG__) && defined (size_t))
typedef __SIZE_TYPE__ size_t;
// ...
Run Code Online (Sandbox Code Playgroud)

它仅适用于VS中的Linux项目,而不适用于Windows项目.

有没有任何已知的解决方案(除了"不要使用using namespace std;:)"?

更新:向Microsoft报告此问题:https://developercommunity.visualstudio.com/content/problem/67405/ambiguous-symbol-size-t-in-linux-projects-when-usi.html

Upd2:微软称他们修复了它,解决方案将在下一次更新中:https://developercommunity.visualstudio.com/content/problem/67405/ambiguous-symbol-size-t-in-linux-projects-when-usi html的

n. *_* m. 6

看起来Microsoft和其他与typedef进出命名空间相关的编译器之间存在差异.

这个源文件

namespace foo { typedef int moo; }
typedef int moo;
using namespace foo;
extern moo a;
Run Code Online (Sandbox Code Playgroud)

用g ++和clang ++编译(没有警告--Weverything).由于符号模糊,MSVC拒绝它.

这正是size_tgcc标题中的情况.它的内部和外部都是typedefed namespace std.这似乎不会导致g ++出现任何问题.

为什么用g ++而不是用msvc编译呢?我想这是因为对7.1.3/3的不同解释

在给定的非类作用域中,可以使用typedef说明符重新定义该作用域中声明的任何类型的名称,以引用它已引用的类型.

不可否认,g ++的解释相当宽松.第一个moo未在声明范围内,namespace ::因此该规则似乎不适用.我找不到任何可以允许这样的事情.

为了解决这个问题,我将修补size_t在全局命名空间中定义的头部,并将声明置于其中namespace std(有条件地,如果__cplusplus已定义).但我没有测试过它(这里没有VC2017)并且无法保证它能够正常工作.

我也不知道为什么你的代码被实际编译器接受并且只被IntelliSense拒绝.我用实际的编译器测试了这个结构.(更新到最后一句:我已经测试了代码,并被MSVC拒绝.我已经进行了测试,然后才意识到"上面的实际编译器"实际上是gcc而不是MSVC).