"std :: string const&s"和"const std :: string&s"有什么区别?

Tho*_*ood 14 c++ const reference notation c++11

我一直在寻找有关如何做某事的例子,并看到了这两个变种:

std::string const &s;
const std::string &s;
Run Code Online (Sandbox Code Playgroud)

在不同的片段.

thx你的答案:)

man*_*lio 12

std::string const &相当于const std::string &.

const std::string &是Stroustrup的C++编程语言采用的风格,可能是"传统风格".

std::string const & 可以比替代方案更一致:

这种正常的风格总是把const它所包含的东西放在右边,而另一种风格有时会把它const放在左边,有时放在右边.

使用const-on-the-style样式,const的局部变量用右边的const定义:int const a = 42;.类似地,const的静态变量定义为static double const x = 3.14;.基本上每一个都const在它所支配的东西的右边,包括const需要在右边的东西:使用const成员函数.

(有关详细信息,请参阅"X const&x"和"X const*p"是什么意思?)

如果您决定使用const-on-the-right样式,请确保不要错误输入std::string const &s为无意义std::string & const s:

上述声明是指:" sconst对" 的引用std::string.这是多余的,因为引用始终是const(您永远不能重置引用以使其引用不同的对象).


Bar*_*rry 7

如前所述,它们是同一类型。喜欢const右侧的原因之一是它如何使用模板。大多数人只是通过替换来处理函数模板。例如:

template <class T> void foo(const T& arg);

int* p;
foo(p);
Run Code Online (Sandbox Code Playgroud)

的类型是什么arg?你想说const int*&,也就是说,一个引用指向一个指针const int,但这是错误的。文本替换让你失败了。如果你已经写成这样

template <class T> void foo(T const& arg);
Run Code Online (Sandbox Code Playgroud)

然后简单的文本替换会产生正确的类型:int* const&。也就是说,const对 的指针的引用int


Khu*_*zad 5

从技术上讲,它是相同的,没有任何区别.但是在某些调试器中(肯定是lldb),std::string const&即使你写了,也会看到const std::string&.


Che*_*Alf 5

正如 Barry在他的回答中指出的那样,旧的 C 语法(以及该语法的 C++ 扩展)不支持文本替换的概念视图,就像在数学中一样。

因此,直接使用 C 语法通常最好编写T const, not const T,即使当T是简单类型时,这些类型表达式是等效的。写入T const还可以避免多级指针声明中的不一致,例如不能移动char const* const p;最后一个指针。const这说明等价仅适用于声明开头的基类型。

几个月前,我开始了一项实验const T,写作并始终如一地使用该符号。因为在 C++11 之后,这已经成为可能,而无需使用宏。为了支持一致性,我使用命名类型构建器,例如

template< class Some_type >
using Ptr_ = Some_type*;
Run Code Online (Sandbox Code Playgroud)

这样就可以代替从右向左阅读

char const* const p = something;
Run Code Online (Sandbox Code Playgroud)

我可以而且确实写了普通的阅读指导

const Ptr_<const char> p = something;
Run Code Online (Sandbox Code Playgroud)

它有点冗长,但我现在有了一些使用它的经验,认为这是值得的(我对此不确定,这是一个实验)。

主要缺点是,虽然此表示法支持(函数模板)函数参数的类型推导,就像直接使用 C 语法一样,但它不支持auto声明的类型推导。令人高兴的是,由于可以轻松创建初始化程序const,因此唯一有问题的情况是对数组的引用。到目前为止,我的务实解决方案是在这种情况下直接使用 C(或者更确切地说,C++)语法,但我认为这代表了该语言的缺点或漏洞,可能有一些通用的解决方案,可以使事情变得更容易其他情况。

对于我当前的类型构建器(例如 )Ptr_,请参阅Github 上的 cppx/core_language_support/type_builders.hpp 文件。它们包括例如In_函数参数。是的,我发现这也是值得的,尽管有些冗长,但清晰明了,因为它使意图非常明确。然而,cppx 的内容是实验性的,可能会发生变化。链接到此处的特定文件甚至可能会被移动,但它会在附近。:)