C++ “与”的区别是什么;std::字符串常量&;s";及;const std::string&;s";?

C++ “与”的区别是什么;std::字符串常量&;s";及;const std::string&;s";?,c++,c++11,reference,constants,notation,C++,C++11,Reference,Constants,Notation,我正在寻找关于如何做某事的示例,并看到了以下两种变体: std::string const &s; const std::string &s; 在不同的片段中 谢谢你的回答:)技术上是一样的,没有任何区别。但在某些调试器(lldb)中,您将看到std::string const&,即使您编写为const std::string&只是为了证明其他人的断言(我理解rtti不会将constness或voltiness纳入.name()输出) 本测试程序: #include <

我正在寻找关于如何做某事的示例,并看到了以下两种变体:

std::string const &s;
const std::string &s;
在不同的片段中


谢谢你的回答:)

技术上是一样的,没有任何区别。但在某些调试器(lldb)中,您将看到
std::string const&
,即使您编写为
const std::string&
只是为了证明其他人的断言(我理解rtti不会将constness或voltiness纳入
.name()
输出)

本测试程序:

 #include <string>
 #include <iostream>

 using std::string;
 using std::cout;
 using std::cin;

  using std::endl;

  int main()
  {
    std::string t = "BLABLA" ;
    std::string t1 = "BLABLA" ;
    std::string const &s = t;
    const std::string &d = t1;


if (typeid(d) == typeid(s)) 
    cout << "d and s are the same type according to the rtti" << endl;

else
    cout << "d and s are the NOT the same type according to the rtti" <<  endl;
    // here the raw output is exactly the same for both
    cout << typeid(d).raw_name() << endl << typeid(s).raw_name() << endl; 

    cin >> t;
    return 0;
}
#包括
#包括
使用std::string;
使用std::cout;
使用std::cin;
使用std::endl;
int main()
{
std::string t=“BLABLA”;
std::string t1=“BLABLA”;
std::字符串常量&s=t;
常量std::string&d=t1;
if(typeid(d)=typeid(s))

cout
std::string const&
等同于
const std::string&

<>代码> const STD::String和是Stroustrup的C++编程语言采用的风格,可能是“传统风格”。
std::string const&
可以比其他选项更加一致:

右边的const样式总是将
const
放在它所构成内容的右边,而另一种样式有时将
const
放在左边,有时放在右边

在右边的const样式中,一个局部变量const是用右边的const定义的:
int const a=42;
。类似地,一个静态变量const被定义为
static double const x=3.14;
。基本上每个
const
都位于它所构成的对象的右边,包括
const
必须位于右侧:具有常量成员函数

(有关更多详细信息,请参阅)

如果您决定在正确的样式上使用const,请确保不要将
std::string const&s
误键入为无意义的
std::string&const&s

上述声明的意思是:“
s
是对
std::string
const
引用”。
它是多余的,因为引用总是
const
(您永远无法重置引用以使其引用不同的对象)。

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

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

int* p;
foo(p);

简单的文本替换产生正确的类型:<代码> int *const和。即,引用“代码> const <代码>指针>代码> int .< /P> < P>。正如巴里所指出的,旧的C语法(和该语法的C++扩展)不支持文本替换的概念视图,如数学。

因此,直接使用C语法通常最好编写
T const
,而不是
const T
,即使
T
是一个简单类型,这些类型表达式是等价的。编写
T const
也可以避免像
char const*const p;
这样的多级指针声明中的不一致性最后一个
常量
无法移动。这说明等价性仅适用于声明开头的基类型

几个月前,我开始做一个实验,编写
const T
,并始终如一地使用这种表示法。因为在C++11之后,这是可能的,不需要使用宏。为了支持一致性,我使用了命名的类型构建器like

template< class Some_type >
using Ptr_ = Some_type*;
我能并且确实写下普通的阅读指导

const Ptr_<const char> p = something;
constptr\up=something;
它有点冗长,但我现在,有了一些使用它的经验,认为它是值得的(我不确定,这是一个实验)

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


对于我当前的类型生成器,如
Ptr
,请参阅。它们包括函数参数的
。是的,我发现这也是值得的,尽管有些冗长,因为它使意图非常明确。但是,cppx内容是实验性的,可能会更改。链接到此处的特定文件甚至可能是移动了,但它就在那里。:

在语义上没有区别。只是一个喜欢哪种风格的问题。在第一个
s
中是对常量字符串的引用。在第二个
s
中是对常量字符串的引用。也就是说,两者实际上是相同的。相关主题:第一个更一致(const始终位于它引用的类型后面,这是它对指针工作的唯一方式)。第二种更常见。第一种允许您从右到左读取声明:s是对不可变的std::字符串的引用。在对符号进行清理时,您经常会看到常量限定的第一种形式-例如,
c++filt
。向下投票者-我发现了我错的地方,几乎不感谢您。
char const* const p = something;
const Ptr_<const char> p = something;