C++14中std::string的运算符后缀

22

我安装了Clang 3.4,并测试了用于字符串字面量 ""s 的后缀运算符。

#include <string>

//1. using namespace std; // without compile error.
//2. using std::operator ""s; // or without it compile error, too.
// for success compiles, need 1. or 2. line.

int main()
{
    auto s = "hello world"s; 
}

如果我注释掉1和2,就会出现编译错误。但我知道在大型项目中,1-方法很糟糕,2-方法很奇怪。

问:我能否在不编写 using namespace std using std :: operator""s 的情况下使用运算符“”s吗?


2
"2.-method is stranger." 你为什么觉得这很奇怪?在我看来,它很自然。 - Suma
1
简短回答:不行。这是预期的方式,Clang 要求 1 或 2 是正确的。看起来你对此并不满意,想要质疑它的定义方式,但这不是 SO 上适当的问题。 - Daniel Frey
9
我们真的需要使用using来使字面量后缀生效吗?太难以想象了。 - Lightness Races in Orbit
3
这些运算符已在内联命名空间中定义,因此你可以使用 using namespace std::literals::string_literals; (例如在使用它们的函数内部) 。 - dyp
10
using namespace std::literals 也可以起作用。 - Howard Hinnant
显示剩余11条评论
2个回答

25

总结评论:

你必须使用using显式地引入那些运算符。这是标准所期望的。你应该只引入你需要的内容。

using namespace std::literals;
或者
using namespace std::literals::string_literals;

根据您的需求,如果有疑问,则后者更可取(只拉入所需内容,而不是更多)。与所有使用声明或指令一样,您希望将它们限制在最小的实用范围内。

需要明确提取运算符的原因是后缀可能会在未来的扩展中在不同的上下文中被重复使用。


std::literals; 和 std::literals::string_literals; 是标准的内联命名空间,还是仅用于编译器实现命名空间? - Khurshid
1
@Khurshid 它们是标准化的,因此具有可移植性。请参见“Header <string> synopsis”末尾的“§21.3 String classes [string.classes]”。 - Daniel Frey
1
@Khurshid 他们将这些namespace内联标准化,以便using std;会引入字面运算符。其他结果被认为是令人惊讶的。 - emsr
@DanielFrey:考虑使用auto s = "hello world"s; std::cout<<typeof(s);在这种情况下,s的类型是否保证被推断为std::string? - Destructor
@PravasiMeet 是的,这是有保证的。 - Daniel Frey
@DanielFrey:好的,明白了。谢谢。 - Destructor

2
如果您觉得第二个选项很奇怪,其实这是相当常见的,您可以像这样限制“using namespace std”的范围:
int main()
{
    using namespace std;
    auto s = "hello world"s; 
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接