为啥 std:set (带有单个冒号)可以编译?
Posted
技术标签:
【中文标题】为啥 std:set (带有单个冒号)可以编译?【英文标题】:Why can std:set (with a single colon) compile?为什么 std:set (带有单个冒号)可以编译? 【发布时间】:2018-08-28 03:01:21 【问题描述】:不小心写了
std::set<string> keys;
作为:
std:set<string> keys;
但奇怪的是,Visual Studio 2013 仍然可以编译。
为什么会这样?
其实keys
不仅是定义的,而是后来作为一组字符串使用的,比如
if(keys.find(keystr)==keys.end())
keys.insert(keystr);
toret.push_back(tempv);
【问题讨论】:
std:
被解释为label
的goto
。见:en.cppreference.com/w/cpp/language/goto
【参考方案1】:
在块范围内,一个标识符后跟一个冒号会引入一个标签。因此,您的陈述相当于:
set<string> keys;
除了它带有标签std
并且可以通过语句goto std;
跳转到。
由于某种原因,名称 set
为编译器所知 --- 可能您使用了 using namespace std;
或 using std::set;
或类似的东西,或者您在某处定义了自己的 set
类型。
【讨论】:
这是避免using namespace std;
和using std::set;
的另一个原因
对using namespace std
/using std::set
提出了很好的论据,但我不确定这是其中之一......主要论据通常是命名空间是为了防止冲突,但如果有一个非标准的“集合”要与之碰撞,那么std: set<...>
可能是有效的。通常的做法是将任何此类 using 声明限制为另一个名称空间/函数,但这个问题很容易在该范围内发生。我更愿意期望在重写std::chrono::high_resolution_clock
等时出现错字而不是这个标签错字(我第一次看到这样的错误)。【参考方案2】:
在第二种情况下,std 是一个标签。这与在 case 语句中拼错 default 相同。
【讨论】:
以上是关于为啥 std:set (带有单个冒号)可以编译?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 std::remove 需要 const 版本的迭代器? [复制]
为啥 std::unordered_set 不将 CComBSTR 类型作为键?