1

I am making a little experiment to test const-ness of data referred to by shared pointers, and of the pointers themselves. I wrote the following code:

#include <iostream>
#include <vector>
#include <memory>
#include <type_traits>

using std::cout;
using std::endl;
using std::vector;
using std::shared_ptr;

auto testfun(const shared_ptr<const vector<int>> &vec){
    cout<<std::is_const<const shared_ptr<const vector<int>>&>::value<<endl; // not const?
    cout<<std::is_const<decltype(vec)>::value<<endl;  // not const?
    cout<<std::is_const<decltype(*vec)>::value<<endl; // not const?
    cout<<std::is_const<decltype(&vec)>::value<<endl; // not const?
}

int main(){
    const vector<int> myvec = {3,3,3,3,3,3};
    const shared_ptr<const vector<int>> vec = 
         std::make_shared<const vector<int>>(myvec);
    cout<<std::is_const<decltype(vec)>::value<<endl; // is const
    testfun(vec);
    return 0;
}

The output of this code is:

1
0
0
0
0

Can someone explain why the last four checks do not qualify as const? I am especially curious as to why std::is_const<decltype(vec)> does not have const type traits.

Nikos Kazazakis
  • 792
  • 5
  • 19
  • You can simplify the test as `std::is_const`, and see https://stackoverflow.com/questions/30806863/whats-the-equivalent-of-stdis-const-for-references-to-const – Ry- Mar 11 '17 at 01:44
  • @Ryan True, but I was curious to see how it works with shared_ptrs since I am using them everywhere and never tested this rigorously. Why does a const reference not qualify as const? – Nikos Kazazakis Mar 11 '17 at 01:48
  • @nikaza Because a reference isn't even an object. Whatever it refers to may be `const`, but a reference never is. – Baum mit Augen Mar 11 '17 at 01:49
  • @nikaza, A reference isn't `const` - it can't be `const`. For every person who says that `is_const` should check `is_const>`, there's going to be another saying that it doesn't make sense. – chris Mar 11 '17 at 01:52
  • @Ryan Great link, thanks. That's very curious though, seeing as a reference is const by definition (i.e., it always refers to the same thing). An `int` is not an object either, but it can qualify as `const`. Is there a fundamental difference I am missing? – Nikos Kazazakis Mar 11 '17 at 01:52
  • @chris Fair enough, I see you point. Why is `std::is_const` not `const` though? – Nikos Kazazakis Mar 11 '17 at 01:53
  • @nikaza: An `int` is an object. As for why a const reference isn’t just considered const… I don’t know. Seems a bit arbitrary. Maybe it’s consistent with some other part of the spec. The important thing is that it’s well-defined and easy to get the behaviour you want, I think. – Ry- Mar 11 '17 at 01:54
  • @Ryan Are you sure about this? An int has no members, and cannot be inherited. In python sure, its an object, but isn't it just a data primitive in c++? – Nikos Kazazakis Mar 11 '17 at 01:56
  • @nikaza: “object” has a specific meaning in C++: http://en.cppreference.com/w/cpp/language/object You might be more familiar with the Java/.NET definition. – Ry- Mar 11 '17 at 01:57
  • @Ryan Ah that's very helpful, thanks! :) – Nikos Kazazakis Mar 11 '17 at 01:58
  • @nikaza, `decltype(vec)` in `testFun` is a reference. – chris Mar 11 '17 at 02:06
  • @chris Yes, now it makes sense, thanks. What about `std::is_const` though? Doesn't this dereference the original one? – Nikos Kazazakis Mar 11 '17 at 02:10
  • The result of dereferencing a `shared_ptr` is also a reference. – chris Mar 11 '17 at 02:24
  • Hmmm I expected that to be a const shared_ptr. I'll look into it some more to understand the chain of causality. Thanks for taking the time :) – Nikos Kazazakis Mar 11 '17 at 02:26

0 Answers0