8

読み取り専用の std:map データ構造が必要です。つまり、一度データを入力してから、それらの値を読み取るだけで、値を変更したり追加したりしないでください。

私の非 const バージョンは次のようになります。

//in .h
#include <string>
#include <map>

std::map<std::string, int> myMap;
void initMap();

//in .cpp
#include "foo.h"

void initMap() {
  myMap["Keys"] = 42;
}

initMap()次に、コード内で 1 回呼び出すだけで完了です。

ここですでにいくつかの質問を読みましたが、マップの const-ness を達成することは自明ではないようです。

にすると、std::map<std::string, const int>に入力できなくなりますinitMap()。コピー コンストラクターは非 const バージョンを入力として簡単に取得できないため、非 const temp と定義のコピー コンストラクターを入力しても機能しません。

これconst std::map<std::string, int>を (定義中に const 以外のコピーで埋めることができる) にすると、[]値アクセスに演算子を使用できなくなります。

const-ness (値) を達成し、構造を初期化する方法はありますか (できればヘッダー ファイルで)。

ところで:C++0xもC++11もboost::オプションではありません。

4

5 に答える 5

15

insert()で利用可能な方法を使用できませんでしたstd::mapか?

http://www.cplusplus.com/reference/map/map/insert/

編集:(解決策)myMap.insert(std::pair<std::string, const int>("Keys", 42));

私が理解している限り、これが機能する理由は、ペアのコンストラクター がpair (const first_type& a, const second_type& b)そのメンバーfirstを初期化し、とsecondのコンストラクターを使用して、とをそれぞれのパラメーターとして取るためです。first_typesecond_typeab

あなたが使用しようとしていたソリューションでは、私の理解では、デフォルトのコンストラクター for を使用して(タイプの)myMap["Keys"] = 42;のメンバーを初期化しsecondます。次に、そのメンバーに値を割り当てようとします。これは class のコンストラクタの外で行われるため、宣言によってこれが不可能になります。mapconst intintmapconst

を使用したソリューションinsert()では、メンバは のコンストラクタで初期化されpairます。したがって、宣言することができますconstpairを にコピーする場合も同様mapです。

于 2013-05-23T08:28:57.150 に答える
2

最も簡単な解決策は、標準のマップ クラスをラップして独自に作成することです。

template <typename KeyType, typename MappedType, typename CmpType>
class ConstantMap
{
    typedef std::map<KeyType, MappedType, CmpType> Impl;
    Impl myImpl;
public:
    typedef Impl::value_type value_type;

    template <ForwardIterator>
    ConstantMap( ForwardIterator begin, ForwardIterator end, CmpType cmp = CmpType() )
        : myImpl( begin, end, cmp )
    {
    }

    //  necessary if [] is not going to work for missing keys
    bool contains( KeyType const& key ) const
    {
        return myImpl.find( key ) != myImpl.end();
    }

    MappedType const& operator[]( KeyType const& key ) const
    {
        Impl::const_iterator elem = myImpl.find( key );
        if ( elem == myImpl.end() ) {
            //  Not found, do what you want (maybe throw an exception)
        }
        return elem.second;
    }
};

に変換できるもののシーケンスにイテレータを渡すことで、マップを初期化できますvalue_type

必要に応じて、追加の転送 typedef、関数などを追加することができます。C++11 を使用している場合は、リスト初期化子を使用できるコンストラクターを作成することもできます。

于 2013-05-23T08:38:03.970 に答える
0

フットプリントが小さく、より高速な、はるかに単純なもの:

static const int MyMapData[] = {
    42 // インデックス 0 は「キー」にマップされます
};

構造体 MyMap { const int& operator[](std::string key) const { スイッチ (キー) { ケース "キー": MyMapData[0] を返します。

default: return NotANumber; // Return 0 and raise an assertion, or return "Not a Number". } }

};

メンテナンスが簡単で、テンプレートを使用せず、ブースト ライブラリを使用せず、どこでもコンパイル可能です。

于 2016-08-16T08:44:12.560 に答える