2017-02-16 23 views
2

C++のより基本的な側面についてはかなり知識がありますが、時には混乱する傾向があります。私はstd::vectorのインスタンスで動作し、それらの値を変更せずにいくつかの操作を行う機能のペアを実装しようとしています。当然、私はconst&による合格は合理的なことと思った。ただし、以下MWEはコンパイルに失敗し、私は理由を理解したいと思います:エラーメッセージがやや次のようになりますC++のconstベクトル参照引数

#include<vector> 

void func1(const std::vector<const char* const>& v){ 
    // do stuff 
} 

void func2(const std::vector<const std::vector<const char* const> >& v){ 
    for(int i=0;i<v.size();++i){ 
    func1(v[i]); 
    } 
} 

int main(){ 
    return 0; 
} 

In file included from...include/c++/4.9.3/x86_64-unknown-linux-gnu/bits/c++allocator.h:33:0, 
       from...include/c++/4.9.3/bits/allocator.h:46, 
       from...include/c++/4.9.3/vector:61, 
       from test.cxx:2: 
.../ext/new_allocator.h: In instantiation of ‘class __gnu_cxx::new_allocator<const std::vector<const char* const> >’: 
.../bits/allocator.h:92:11: required from ‘class std::allocator<const std::vector<const char* const> >’ 
.../ext/alloc_traits.h:172:53: required from ‘struct __gnu_cxx::__alloc_traits<std::allocator<const std::vector<const char* const> > >’ 
.../bits/stl_vector.h:75:28: required from ‘struct std::_Vector_base<const std::vector<const char* const>, std::allocator<const std::vector<const char* const> > >’ 
.../bits/stl_vector.h:214:11: required from ‘class std::vector<const std::vector<const char* const> >’ 
test.cxx:9:18: required from here 
.../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 std::vector<const char* const>; __gnu_cxx::new_allocator<_Tp>::const_pointer = const std::vector<const char* const>*; __gnu_cxx::new_allocator<_Tp>::const_reference = const std::vector<const char* const>&]’ cannot be overloaded 
     address(const_reference __x) const _GLIBCXX_NOEXCEPT 
    ^
.../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 std::vector<const char* const>; __gnu_cxx::new_allocator<_Tp>::pointer = const std::vector<const char* const>*; __gnu_cxx::new_allocator<_Tp>::reference = const std::vector<const char* const>&]’ 
     address(reference __x) const _GLIBCXX_NOEXCEPT 
    ^
.../ext/new_allocator.h: In instantiation of ‘class __gnu_cxx::new_allocator<const char* const>’: 
.../bits/allocator.h:92:11: required from ‘class std::allocator<const char* const>’ 
.../ext/alloc_traits.h:172:53: required from ‘struct __gnu_cxx::__alloc_traits<std::allocator<const char* const> >’ 
.../bits/stl_vector.h:75:28: required from ‘struct std::_Vector_base<const char* const, std::allocator<const char* const> >’ 
.../bits/stl_vector.h:214:11: required from ‘class std::vector<const char* const>’ 
test.cxx:10:14: required from here 
.../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 char* const; __gnu_cxx::new_allocator<_Tp>::const_pointer = const char* const*; __gnu_cxx::new_allocator<_Tp>::const_reference = const char* const&]’ cannot be overloaded 
     address(const_reference __x) const _GLIBCXX_NOEXCEPT 
    ^
.../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 char* const; __gnu_cxx::new_allocator<_Tp>::pointer = const char* const*; __gnu_cxx::new_allocator<_Tp>::reference = const char* const&]’ 
     address(reference __x) const _GLIBCXX_NOEXCEPT 

私は実際にそのエラーメッセージによって混乱していますfunc2の中のfunc1の呼び出しを参照して、何かが過負荷にならないと主張する。ベクタエントリへの参照を解決する問題があるようですが、なぜこのコードがコンパイルされないのか分かりません。私はこのタイプの動作に関する説明、提案、またはドキュメントへのポインタがあればうれしいです。

答えて

2
std::vector<const char* const> 

あなたはconstタイプのベクトルをインスタンス化しようとしています。タイプは少なくとも可動性である必要がありますが、そうではありません。変更:あなたはちょうどそれが何を意味するのか事前に知っていれば

std::vector<const char*> 

ではなく

+0

@nwp:はい、私はmove-assignableを意味しました。 –

+0

提案していただきありがとうございます。残念ながら、 'func2'のエラーは依然として残っているので、これは実際には問題を解決しません。 'func2'のヘッダ内の内側のベクトルから' const'も削除して、コンパイルに成功させる必要があります。 – carsten

+0

はい。私は「どこでもあなたは 'char const * const'のベクトルを変更しました」という意味です。 –

3

コンパイラが、正しくその問題を報告します。

std::allocatorには、addressの2つのオーバーロードがあります。

address(reference __x) 
address(const_reference __x) 

コンパイラの問題は、テンプレートの種類const Tのために、2種類のT&const T&が同じ型になるということです。そして、それは同じ過負荷の2つのコピーがあると信じています。

+0

これは意味があります。しかし、どのように私はこの問題を避けるのですか? – carsten

+0

ああ!そのため、オーバーロードの1つしか持たない独自のアロケータを作成すると、そのアロケータをベクトルのアロケータとして使用することができ、すべてがうまく動作します! –

+0

@carsten: 'char const * const'ではなく、ベクトル:' char const * 'で非const型を使うだけです。 –

関連する問題