2016-08-22 9 views
-1

私はこの機能を持っている:const functionキーワードでmap []演算子を使用できませんか?

カードはクラスであり、表が持つクラスである
bool Table::FindCard(const int& i, const Card& card) const{ 
    std::vector<Card>::const_iterator iter = table[i].begin(); 
    for(; iter != table[i].end() ; ++iter){ 
    if(*iter == card){ 
     return true; 
    } 
    } 

    return false; 
} 

Table.cc: In member function ‘bool Table::FindCard(const int&, const  Card&) const’: 
Table.cc:42:50: error: passing ‘const t_map {aka const std::map<int,  std::vector<Card> >}’ as ‘this’ argument discards qualifiers [-fpermissive] 
std::vector<Card>::const_iterator iter = table[i].begin(); 
:私は、私はこのエラーを取得するコードを実行した場合

std::map<int, std::vector<Card> > table; 

しかし、constというキーワードを削除した場合:

bool Table::FindCard(const int& i, const Card& card){ 
... 
} 

すべての作品。

なぜなら、演算子[]はconstではないからです。 const関数は他のconst関数だけを呼び出すことができます。

おかげ

+0

あなたは( 'cbeginを試してみました) '? –

+2

_理由は、演算子[]がconstでないためですか? "はい、[ここ](http://en.cppreference.com/w/cpp/container/map/operator_at)を参照してください。 –

答えて

3

The reason is because operator[] isn't const? I know that a const function can call only other const function.

はい。 operator[]は、キーが存在しない場合に新しいdefault-constructed要素を作成するように指定されており、constマップ上ではそれは意味をなさないため、constとマークされていません。もちろん

あなたは例外をスローするconstバージョンを指定(atが行うように)、または可能性 - 鍵が見つからない場合terminateを呼び出しますが、標準悲しいかなそれを言っていない - 私は知りません。 atまたは(ugh)findを使用する必要があります。

0

std::mapの場合、operator[]は、指定されたキーに関連付けられた値への参照を返します。そのキーが存在しない場合は、そのキーが挿入されます。これは明らかにマップを変更するので、この関数はconstではなく、constオブジェクトに対して呼び出すことはできません。

2

operator []は、キーがまだ存在しない場合は、要素をマップに挿入します。これはconst演算ではありません。 constを保持するためにmap.at()を使用してください。

0

すでに言われたように:operator[]no-contのメンバーですが、atと置き換えることができます。

視覚的な例を挙げると、これまでの回答にというコンパイル可能なコードを追加したいだけです。

bool Table::FindCard(const int& i, const Card& card) const{ 
    std::vector<Card>::const_iterator iter = table.at(i).begin(); 
    for(; iter != table.at(i).end() ; ++iter){ 
    if(*iter == card){ 
     return true; 
    } 
    } 

    return false; 
} 
0

すべてのC++ライブラリの決定と同様に、この根本には哲学的な疑問があります。

vectorでは、operator[]がconstとnon-constの両方の場合について定義されています。長さNのベクトルの場合、operator[](0...N-1)となるので、constであろうとなかろうと、常にの意味を持つからです。要素が存在します。

これをベースラインとして、地図はどうすればよいですか?下付き文字(キー)がまったく存在するかどうかを判断する絶対的な基準はありません。

可変要素operator[]を使用すると、要素のデフォルト構成を選択することは妥当です。すべての呼び出し元がそれを参照した後、彼はそれが存在することを期待しており、存在できると考えます。これは、少なくとも驚きのパスです。

不変の場合はどうなりますか?要素は存在していても存在しなくてもよく、存在しない場合は、constの精神に違反するので、マップを変更することはできません。

vectorを扱うことに慣れていた人にとっては、例外が発生する可能性があるため、例外をスローする必要はありません。次に、非常に異なる動作を持つ2つの同様の外観のインターフェースがあります。

答えは、可変演算子[]をまったく提供しないことです。開発者は(あなたのように)それが存在しないことに気付くかもしれませんが、ドキュメントを見て間違ったツリーを吠えていることに気づく機会があります。

前述したように、at()(ベクトルのように添字が存在しない場合は例外をスローします)とfind()があります。

私たちは自分自身の効用関数を与えることができますブーストから(そしてすぐに、++ 17 C)少しの助けを借りて

#include <map> 
#include <string> 
#include <utility> 
#include <type_traits> 
#include <iostream> 
#include <boost/optional.hpp> 


template<class Map> 
auto maybe_get_impl(Map& map, typename Map::key_type const& key) 
{ 
    using reference_type = std::conditional_t< 
    std::is_const<std::remove_reference_t<Map>>::value, 
    typename Map::mapped_type const&, 
    typename Map::mapped_type&>; 
    boost::optional<reference_type> result; 
    auto ifind = map.find(key); 
    if (ifind != map.end()) 
    { 
     result = ifind->second; 
    } 
    return result; 
} 

template<class K, class V, class Comp, class A> 
auto maybe_get(std::map<K, V, Comp, A> const& map, K const& key) 
{ 
    return maybe_get_impl(map, key); 
} 

template<class K, class V, class Comp, class A> 
auto maybe_get(std::map<K, V, Comp, A>& map, K const& key) 
{ 
    return maybe_get_impl(map, key); 
} 

int main() 
{ 
    std::map<int, std::string> mymap; 
    mymap.emplace(1, "hello"); 
    mymap.emplace(2, "world"); 

    // note: non-const because we're taking a reference from a mutable map; 
    std::string part = std::string("goodbye, cruel world"); 

    std::cout << maybe_get(mymap, 1).value_or(part) << std::endl; 
    std::cout << maybe_get(mymap, 2).value_or(part) << std::endl; 
    std::cout << maybe_get(mymap, 0).value_or(part) << std::endl; 
} 

予想される出力:

hello 
world 
goodbye, cruel world 
関連する問題