0

I have two questions.

First of all I have a little problem with the understanding of const pointers to const values. I don't get why B::insert works, while C::insert results in a compiler error. I mean doesn't the list in C exactly equals the parameter of C::insert?

My second question is whether A const * const a, could also be written as const A& a.

class A
{
    //Do stuff
};

class B 
{
private:
    list<A const *> l;

public:
    void insert(A const * const a)
    {
        l.push_back(a);
    }
};

class C 
{
private:
    list<A const * const> l;

public:
    void insert(A const * const a)
    {
            l.push_back(a);
    }
};

Edit (Compile error):

g++ -Wall  -c  -O2 "sonnensystem.cpp" -std=c++11 (im Verzeichnis: C:\Users\Kenan\Desktop\OPR\cppcode\Konzepte\Kapselung\Architektur\sonnensystem01)
In file included from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/x86_64-w64-mingw32/bits/c++allocator.h:33:0,
             from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/bits/allocator.h:46,
             from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/string:41,
             from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/bits/locale_classes.h:40,
             from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/bits/ios_base.h:41,
             from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/ios:42,
             from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/ostream:38,
             from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/iostream:39,
             from sonnensystem.cpp:1:
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/ext/new_allocator.h: In instantiation of 'struct __gnu_cxx::new_allocator<const A* const>':
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/bits/allocator.h:92:11:   required from 'class std::allocator<const A* const>'
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/bits/stl_list.h:315:9:   required from 'class std::__cxx11::_List_base<const A* const, std::allocator<const A* const> >'
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/bits/stl_list.h:507:11:   required from 'class std::__cxx11::list<const A* const>'
sonnensystem.cpp:28:27:   required from here
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/ext/new_allocator.h:93:7: error: 'const _Tp* __gnu_cxx::new_allocator<_Tp>::address(__gnu_cxx::new_allocator<_Tp>::const_reference) const [with _Tp = const A* const; __gnu_cxx::new_allocator<_Tp>::const_pointer = const A* const*; __gnu_cxx::new_allocator<_Tp>::const_reference = const A* const&]' cannot be overloaded
       address(const_reference __x) const _GLIBCXX_NOEXCEPT
       ^
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/ext/new_allocator.h:89:7: error: with '_Tp* __gnu_cxx::new_allocator<_Tp>::address(__gnu_cxx::new_allocator<_Tp>::reference) const [with _Tp = const A* const; __gnu_cxx::new_allocator<_Tp>::pointer = const A* const*; __gnu_cxx::new_allocator<_Tp>::reference = const A* const&]'
       address(reference __x) const _GLIBCXX_NOEXCEPT
       ^
Kompilierung fehlgeschlagen.
1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
Sali Ke
  • 11
  • 1
  • 4
  • Would be useful if you would include the compiler error. My compiler did not have an error. – Eljay Dec 31 '17 at 02:36
  • @Eljay See my edit. I also tried this online compiler [link](http://cpp.sh/). Didn't work there either :/ – Sali Ke Dec 31 '17 at 02:44
  • Also see [Does C++11 allow `vector`?](https://stackoverflow.com/questions/6954906/does-c11-allow-vectorconst-t) for why the compiler complains about `address`. – Bo Persson Dec 31 '17 at 12:04

3 Answers3

3

In your declaration A const * const, the first const says that the A * pointer points to a value that can't be changed (a const pointer). The second const says that the value of that pointer can't be changed, just like a const int can't be changed. Since list (and other standard containers) require their members to be assignable, they can't be const values.

For your second question, a A const * const and const A& are similar, but not interchangeable, as the ways you use them are different.

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
  • Thanks, i got that now but why exactly does it need to be CopyAssignable? – Sali Ke Dec 31 '17 at 03:14
  • Short answer: Because the language says it needs to be. Longer answer: as containers are copied, created, resized, etc., elements will be moved and copied, so the existing values in the containers need to be updateable (assigned by copying). – 1201ProgramAlarm Dec 31 '17 at 03:15
  • Alright thank you for your help :) Is @SoronelHaetir's comment right, tho? I tried it but don't seem to work ;/ Don't want to get this thread closed before knowing whether his answer is correct or not :D – Sali Ke Dec 31 '17 at 03:37
  • @SaliKe No, using `emplace_back` will not let it work. There's more going on internally than just creating the node. – 1201ProgramAlarm Dec 31 '17 at 06:24
1

When using std::list<T>, one of the requirements for T is that it is CopyAssignable. See http://en.cppreference.com/w/cpp/container/list.

When you use a const type as the parameter, that requirement is not met. You will see a similar error, if not the same error, if you use:

std::list<const int> a;
a.push_back(10);

Anyway,

list<A const * const> l;

is not usable.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
0

The only real difference between A const * const and A const & is that it is easier to check that the pointer is invalid (you could cast a nul pointer to A and then dereference to get a null A reference, it's just easier to go if(!a)).

The C::insert case is due to the code trying to assign to the internal node value. It would probably work if you used emplace_back instead of push_back.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
SoronelHaetir
  • 14,104
  • 1
  • 12
  • 23
  • I tried to use emplace_back instead of push_back but that didn't work. I think like the other people around here stated already, the generic argument needs to be CopyAssignable. – Sali Ke Dec 31 '17 at 03:16