What is the difference between “std::string const &s” and “const std::string &s”?

牧云@^-^@ 提交于 2019-12-06 18:07:44

问题


I was looking for examples on how to do something and saw this two variants:

std::string const &s;
const std::string &s;

in different snippets.

thx for your answer :)


回答1:


std::string const & is equivalent to const std::string &.

const std::string & is the style adopted in Stroustrup's The C++ Programming Language and probably is "the traditional style".

std::string const & can be more consistent than the alternative:

the const-on-the-right style always puts the const on the right of what it constifies, whereas the other style sometimes puts the const on the left and sometimes on the right.

With the const-on-the-right style, a local variable that is const is defined with the const on the right: int const a = 42;. Similarly a static variable that is const is defined as static double const x = 3.14;. Basically every const ends up on the right of the thing it constifies, including the const that is required to be on the right: with a const member function.

(see What do “X const& x” and “X const* p” mean? for further details).

If you decide to use const-on-the-right style, make sure to don't mis-type std::string const &s as the nonsensical std::string & const s:

The above declaration means: "s is a const reference to a std::string". It's redundant since references are always const (you can never reset a reference to make it refer to a different object).




回答2:


Technically it is the same and does not make any difference. But in some debuggers (lldb for sure) you will see std::string const& even if you have written as const std::string&.




回答3:


Just to prove other people assertations (I understand that rtti doesn't take constness or voltilness into the .name() output )

this test program:

 #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;
}

both for gcc (4.9.2) (with proper modifications) msdn (vs2010) returns "same type" for both.

I purpose this "answer" as a contributation and not as an "answer".

EDIT: Reading item 4 in "Effective Modern C++" of Scott-Meyers shares some really interesting hidden information about the example I wrote. In short, typeid doesn't yield reliable results since we are passing variable names by value. When we are passing a method a variable by value, the deduced type loses its constness and volatilness and referenceness (for the love of god will be shortened to cvr) . That's why the above example doesn't prove if there is difference between the two types.

The same Item states that Boost project hosts a library called TypeIndex, which preserves cvr properties.




回答4:


As noted, they're the same type. One reason to like the const on the right is how it plays with templates. Most people process function templates by just substitution. For example:

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

int* p;
foo(p);

What is the type of arg? You want to say const int*&, which is to say, a reference to a pointer to const int, but that is wrong. Text substitution has failed you. If you has written it instead like

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

Then simple text substitution yields the correct type: int* const&. That is, a reference to const pointer to int.




回答5:


As Barry noted in his answer the old C syntax (and the C++ extension of that syntax) doesn't support the conceptual view of text substitution, as in mathematics.

Using the C syntax directly it's therefore generally a good idea to write T const, not const T, even though when T is a simple type these type expressions are equivalent. Writing T const also avoids inconsistency in a multi-level pointer declaration like char const* const p;, where the last const can't be moved. Which exemplifies that the equivalence is only for the base type at the start of a declaration.

Some months ago I started an experiment writing const T, and using that notation consistently. Because that's now possible after C++11, without using macros. To support the consistency I use named type builders like

template< class Some_type >
using Ptr_ = Some_type*;

so that instead of the read-from-right-to-left

char const* const p = something;

I can and do write the ordinary reading direction

const Ptr_<const char> p = something;

It's little bit more verbose, but I now, with some experience using it, think it's worth it (I was not sure about that, it was an experiment).

The main drawback is that while this notation supports type deduction for (function template) function arguments just like direct use of C syntax, it does not support type deduction for auto declarations. Happily, since an initializer can easily be made const, about the only problematic case is reference to array. My pragmatic solution so far has been to use the C (or rather, C++) syntax directly in such cases, but I think this represents a shortcoming of or hole in the language, possibly with some general solution that would make things much easier also in other contexts.

For my current type builders like Ptr_, see the cppx/core_language_support/type_builders.hpp file at Github. They include e.g. In_ for function arguments. And yes, I've found that also worth it, in clarity, in spite of some verbosity, because it makes the intent very clear. However, the cppx stuff is experimental and subject to change. The specific file linked to here may even be moved, but it will be thereabouts. :)



来源:https://stackoverflow.com/questions/35913098/what-is-the-difference-between-stdstring-const-s-and-const-stdstring-s

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!