2017-12-31 46 views
0

私には2つの質問があります。C++のconst値へのconstポインタの理解

まず、const値のconstポインタの理解に少し問題があります。私はなぜB::insertが働くのか理解しません。一方、C::insertはコンパイラエラーに繋がります。私は、Cのリストが正確にC::insertのパラメータと同じではないことを意味しますか?

私の2番目の質問は、A const * const aconst 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); 
    } 
}; 

編集(コンパイルエラー):あなたの宣言A const * const

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. 
+0

コンパイラエラーを含めると便利です。私のコンパイラにはエラーはありませんでした。 – Eljay

+0

@Eljay私の編集を参照してください。私はこのオンラインコンパイラ[リンク](http://cpp.sh/)も試しました。/ –

+0

なぜ[C++ 11では 'vector '?](https://stackoverflow.com/questions/6954906/does-c11-allow-vectorconst-t)を許可していますか?コンパイラは 'アドレス'について不平を言う。 –

答えて

3

、最初constを変更することはできません値にA *ポインタポイント(のconstポインタ)と述べています。 2番目のconstは、const intが変更できないように、そのポインタの値を変更することはできないと言っています。 list(および他の標準コンテナ)はメンバーを割り当てる必要があるため、const値にすることはできません。

2番目の質問では、使用方法が異なるため、A const * constconst A&は似ていますが、互換性はありません。

+0

ありがとう、私は今それを持っていますが、なぜそれがCopyAssignableになる必要がありますか? –

+0

短い答え:言語はそれが必要であると言いますから。より長い答え:コンテナがコピー、作成、サイズ変更されるなど、要素は移動およびコピーされるので、コンテナ内の既存の値は更新可能(コピーによって割り当てられる)である必要があります。 – 1201ProgramAlarm

+0

助けてくれてありがとうございました:) @ SoronelHaetirさんのコメントは正しくありますか?私は試しましたが動作していないようです; /彼の答えが正しいかどうかを知る前にこのスレッドを閉じたくはありません:D –

1

std::list<T>を使用する場合、Tの要件の1つは、CopyAssignableです。 http://en.cppreference.com/w/cpp/container/listを参照してください。

const型をパラメーターとして使用すると、その要件は満たされません。あなたが使用する場合は、同様のエラーを参照してください、そうでない場合は、同じエラーになります。

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

とにかく、

list<A const * const> l; 

は使用できません。

0

A const * constA const &間の唯一の本当の違いは、ポインタが無効であることを確認することが容易であるということである(そして、あなたがAにNULポインタをキャストでき、間接参照ヌルA参照を取得するために、それはif(!a)に行くだけで簡単です) 。

C::insertの場合は、内部ノードの値に割り当てようとしているコードが原因です。 push_backの代わりにemplace_backを使用した場合、おそらく動作します。

+0

私はpush_backの代わりにemplace_backを使用しようとしましたが、動作しませんでした。私は、ここですでに述べられている他の人々のように、一般的な議論はCopyAssignableである必要があると思います。 –

関連する問題