সি ++ তে একটি স্ট্যাটিক স্ট্যান্ডার্ড :: মানচিত্র <<<<<< শুরু করা হচ্ছে


448

স্থির মানচিত্রের সূচনা করার সঠিক উপায় কী? আমাদের কি এমন স্ট্যাটিক ফাংশন দরকার যা এটি শুরু করবে?

উত্তর:


619

সি ++ 11 ব্যবহার করে:

#include <map>
using namespace std;

map<int, char> m = {{1, 'a'}, {3, 'b'}, {5, 'c'}, {7, 'd'}};

বুস্ট.অ্যাসাইন ব্যবহার করুন :

#include <map>
#include "boost/assign.hpp"
using namespace std;
using namespace boost::assign;

map<int, char> m = map_list_of (1, 'a') (3, 'b') (5, 'c') (7, 'd');

115
প্রতিবার যখনই আমি সি ++ এর সাথে এরকম কিছু দেখি, তখন আমি সমস্ত বীভৎস টেম্পলেট কোডটি মনে করি যা অবশ্যই এর পিছনে থাকবে। ভালো উদাহরণ!
গ্রেগ হিউগিল

34
এই সমস্ত ইউটিলিটিগুলি কার্যকর করে এমন সমস্ত ভয়াবহ টেম্পলেট কোডের সৌন্দর্য হ'ল এটি একটি লাইব্রেরিতে ঝরঝরেভাবে আবৃত এবং শেষ ব্যবহারকারীর পক্ষে জটিলতার সাথে খুব কমই মোকাবিলা করা প্রয়োজন।
স্টিভ গুইদি

45
@QBziZ: আপনার কোম্পানীর এটি "মান যথেষ্ট" হচ্ছে না ভিত্তিতে বুস্ট ব্যবহার প্রত্যাখ্যান করে তাহলে, আমি ভাবছি সি ++ লাইব্রেরি কি হবে "মান যথেষ্ট" হতে। বুস্ট হয় সি ++ সংকেতপদ্ধতিরচয়িতা জন্য আদর্শ সহচর।
দেবসোলার

47
বুস্টের সাথে আমার সমস্যা (এখানে এবং অন্য কোথাও) আপনি প্রায়শই এটি ছাড়াই পেতে পারেন (এক্ষেত্রে সি ++ 11 বা কোনও ফাংশন সহ সি ++ 11 এর আগে )। বুস্টের একটি উল্লেখযোগ্য সংকলন টাইম ওভারহেড যুক্ত হয়েছে, আপনার সংগ্রহস্থলটিতে পার্ক করার জন্য প্রচুর ফাইল ছিল (এবং আপনি যদি সংরক্ষণাগার তৈরি করে থাকেন তবে / জিপ / এক্সট্রাক্টের অনুলিপি করতে হবে)। এ কারণেই আমি এটি ব্যবহার না করার চেষ্টা করি। আমি জানি যে আপনি কোন ফাইলগুলি অন্তর্ভুক্ত / অন্তর্ভুক্ত করবেন না তা চয়ন করতে পারেন তবে আপনি সাধারণত বুস্টের ক্রস নির্ভরতা সম্পর্কে নিজেকে চিন্তা করতে চান না তাই আপনি কেবল পুরো জিনিসটি অনুলিপি করতে পারেন।
বোবোবোবো

7
বুস্টের সাথে আমার সমস্যাটি হ'ল এটির প্রায়শই বেশ কয়েকটি নতুন লাইব্রেরি নির্ভরতা থাকে, যার অর্থ সাধারণত আরও বেশি প্যাকেজ রয়েছে যা সঠিকভাবে কাজ করার জন্য ইনস্টল করা প্রয়োজন। আমাদের ইতিমধ্যে libstdc ++ দরকার। উদাহরণস্বরূপ, বুস্ট এএসআইও গ্রন্থাগারটিতে কমপক্ষে 2 টি নতুন গ্রন্থাগার (সম্ভবত আরও বেশি) প্রয়োজন যা ইনস্টল করা দরকার। সি ++ 11/14 এটি বুস্টের প্রয়োজন না হওয়ার জন্য অনেক সহজ করে তোলে।
রাহলি

135

একটি ফাংশন ব্যবহার করার সর্বোত্তম উপায়:

#include <map>

using namespace std;

map<int,int> create_map()
{
  map<int,int> m;
  m[1] = 2;
  m[3] = 4;
  m[5] = 6;
  return m;
}

map<int,int> m = create_map();

18
কেন এটি 'সেরা'? উদাহরণস্বরূপ কেন এটি @ ড্রিমারের উত্তরের চেয়ে ভাল?
লার্নের মারকুইস

6
আমি মনে করি এটি "সেরা" কারণ এটি সত্যই সহজ এবং এটি বিদ্যমান অন্যান্য কাঠামোর উপর নির্ভর করে না (যেমন বুস্ট :: বরাদ্দ করুন বা এর পুনর্নির্মাণ)। এবং @ ড্রিমারের উত্তরের তুলনায়, ভাল, আমি কেবল একটি মানচিত্রের সূচনা করার জন্য একটি সম্পূর্ণ কাঠামো তৈরি করা
এড়াচ্ছি

3
এখানে একটি বিপদ আছে নোট করুনexternএই "মূল রান-টাইম কনস্ট্রাক্টারের আগে" ভেরিয়েবলগুলির সঠিক মান থাকবে না যদি সংকলক কেবল externঘোষণাটি দেখেছে , তবে এখনও আসল পরিবর্তনশীল সংজ্ঞাতে চলেছে না
বোবোবোবো

5
না, বিপদটি হ'ল কিছু বলার অপেক্ষা রাখে না যে কোন ক্রমে স্থিতিশীল ভেরিয়েবলগুলি শুরু করা উচিত (কমপক্ষে সংকলন ইউনিট জুড়ে)। তবে এটি এই প্রশ্নের সাথে যুক্ত কোনও সমস্যা নয়। এটি স্ট্যাটিক ভেরিয়েবলগুলির একটি সাধারণ সমস্যা।
পিয়েরবিডিআর

5
কোনও উত্সাহ এবং কোনও সি ++ 11 => +1 নেই। লক্ষ্য করুন যে ফাংশনটি একটি const map<int,int> m = create_map()(এবং তাই, একটি ক্লাসের struct MyClass {const map<int, int> m; MyClass(); }; MyClass::MyClass() : m(create_map())
কনস্ট

115

উত্সাহের অনুরূপ কিছু করা কোনও জটিল সমস্যা নয়। এখানে ক্রেস্টর সহ মাত্র তিনটি ফাংশন সহ একটি শ্রেণি রয়েছে যা বুস্ট কী করেছে তার প্রায় প্রতিলিপি করতে (প্রায়)।

template <typename T, typename U>
class create_map
{
private:
    std::map<T, U> m_map;
public:
    create_map(const T& key, const U& val)
    {
        m_map[key] = val;
    }

    create_map<T, U>& operator()(const T& key, const U& val)
    {
        m_map[key] = val;
        return *this;
    }

    operator std::map<T, U>()
    {
        return m_map;
    }
};

ব্যবহার:

স্টাড :: ম্যাপ মাইম্যাপ = তৈরি_ম্যাপ <ইন, ইনট> (1,2) (3,4) (5,6);

উপরের কোডটি গ্লোবাল ভেরিয়েবল বা কোনও শ্রেণীর স্থিতিশীল সদস্যদের আরম্ভ করার জন্য সেরা কাজ করে যা প্রাথমিককরণ করা দরকার এবং এটি কখন ব্যবহার করা হবে তা আপনি জানেন না তবে আপনি নিশ্চিত করতে চান যে মানগুলি এতে উপলব্ধ।

যদি বলে, আপনি একটি বিদ্যমান স্ট্যান্ড :: ম্যাপে উপাদানগুলি সন্নিবেশ করিয়ে পেয়েছেন ... আপনার জন্য এখানে আরও একটি ক্লাস রয়েছে।

template <typename MapType>
class map_add_values {
private:
    MapType mMap;
public:
    typedef typename MapType::key_type KeyType;
    typedef typename MapType::mapped_type MappedType;

    map_add_values(const KeyType& key, const MappedType& val)
    {
        mMap[key] = val;
    }

    map_add_values& operator()(const KeyType& key, const MappedType& val) {
        mMap[key] = val;
        return *this;
    }

    void to (MapType& map) {
        map.insert(mMap.begin(), mMap.end());
    }
};

ব্যবহার:

typedef std::map<int, int> Int2IntMap;
Int2IntMap testMap;
map_add_values<Int2IntMap>(1,2)(3,4)(5,6).to(testMap);

এটি এখানে জিসিসি 4.7.2 এর সাথে ক্রিয়াতে দেখুন: http://ideone.com/3uYJiH

###########################################################

সম্পাদনা : map_add_valuesনীচের ক্লাসটি, যা আমি প্রস্তাবিত মূল সমাধান ছিল, এটি জিসিসি 4.5+ এর ক্ষেত্রে আসবে না। অনুগ্রহ করে করার জন্য উপরের কোড তাকান যোগ বিদ্যমান মানচিত্রে মান।


template<typename T, typename U>
class map_add_values
{
private:
    std::map<T,U>& m_map;
public:
    map_add_values(std::map<T, U>& _map):m_map(_map){}
    map_add_values& operator()(const T& _key, const U& _val)
    {
        m_map[key] = val;
        return *this;
    }
};

ব্যবহার:

std :: মানচিত্র <int, int> আমার_ম্যাপ;
// পরে কোথাও কোড বরাবর
map_add_values ​​<int- এ, int-> (my_map) (1,2) (3,4) (5,6);

দ্রষ্টব্য: পূর্বে আমি operator []প্রকৃত মান যুক্ত করার জন্য একটি ব্যবহার করেছি। ডালে মন্তব্য হিসাবে এটি সম্ভব নয় not

#################################################################################################


3
বার্তাগুলির সাথে ত্রুটি-সংখ্যাগুলি (এনাম থেকে) বাঁধতে আমি আপনার প্রথম নমুনাটি <<, স্ট্রিং> হিসাবে ব্যবহার করছি - এটি একটি কবজির মতো কাজ করছে - আপনাকে ধন্যবাদ।
স্ল্যাশমেজ

1
operator[]শুধুমাত্র একটি যুক্তি লাগে।
ডাল

1
@ ডাল: ভাল ধরা! কোনও কারণে আমি ভেবেছিলাম ওভারলোডেড [] অপারেটররা আরও গ্রহণ করতে পারে।
ফ্যালকন ফ্যালকন

2
এটি একটি দুর্দান্ত উত্তর। এটি লজ্জার বিষয় যে ওপি কখনই তাকে বেছে নেয়নি। আপনি মেগা প্রপস প্রাপ্য।
থমাস থারোগড

মানচিত্র_এডিডি_ভ্যালুগুলি জিসিসিতে কাজ করে না, যা অভিযোগ করে: error: conflicting declaration ‘map_add_values<int, int> my_map’ error: ‘my_map’ has a previous declaration as ‘std::map<int, int> my_map’
মার্টিন ওয়াং

42

এখানে আরও একটি উপায় যা 2-উপাদানগুলির ডেটা কনস্ট্রাক্টর ব্যবহার করে। এটি আরম্ভ করার জন্য কোনও ফাংশনের প্রয়োজন নেই। কোনও তৃতীয় পক্ষের কোড (বুস্ট) নেই, কোনও স্ট্যাটিক ফাংশন বা অবজেক্ট নেই, কোন কৌশল নেই, কেবল সাধারণ সি ++:

#include <map>
#include <string>

typedef std::map<std::string, int> MyMap;

const MyMap::value_type rawData[] = {
   MyMap::value_type("hello", 42),
   MyMap::value_type("world", 88),
};
const int numElems = sizeof rawData / sizeof rawData[0];
MyMap myMap(rawData, rawData + numElems);

যেহেতু আমি এই উত্তরটি লিখেছি সি ++ 11 আউট। আপনি এখন নতুন প্রারম্ভিক তালিকা বৈশিষ্ট্যটি ব্যবহার করে সরাসরি এসটিএল পাত্রে শুরু করতে পারেন:

const MyMap myMap = { {"hello", 42}, {"world", 88} };

25

উদাহরণ স্বরূপ:

const std::map<LogLevel, const char*> g_log_levels_dsc =
{
    { LogLevel::Disabled, "[---]" },
    { LogLevel::Info,     "[inf]" },
    { LogLevel::Warning,  "[wrn]" },
    { LogLevel::Error,    "[err]" },
    { LogLevel::Debug,    "[dbg]" }
};

মানচিত্রটি যদি কোনও শ্রেণীর ডেটা সদস্য হয় তবে আপনি নিম্নলিখিত পদ্ধতিতে সরাসরি সিলেক্ট করতে পারেন (সি ++ 17):

// Example

template<>
class StringConverter<CacheMode> final
{
public:
    static auto convert(CacheMode mode) -> const std::string&
    {
        // validate...
        return s_modes.at(mode);
    }

private:
    static inline const std::map<CacheMode, std::string> s_modes =
        {
            { CacheMode::All, "All" },
            { CacheMode::Selective, "Selective" },
            { CacheMode::None, "None" }
            // etc
        };
}; 

24

আমি একটি স্ট্যাটিক অবজেক্টের অভ্যন্তরে মানচিত্রটি গুটিয়ে রাখব এবং এই অবজেক্টটির কনস্ট্রাক্টারে মানচিত্রের সূচনা কোডটি রেখে দেব, আপনি নিশ্চিত হন যে আরম্ভের কোডটি কার্যকর করার আগে মানচিত্রটি তৈরি হয়েছিল।


1
আমি এই এক সাথে আপনার সাথে আছি। এটিও একটি
তাত্পর্যপূর্ণ

2
ত্বকের চেয়ে দ্রুত কি? একটি ইনিশিয়ালাইজার সহ একটি গ্লোবাল স্ট্যাটিক? না, এটি নয় (আরভিও সম্পর্কে মনে রাখবেন)।
পাভেল মিনায়েভ

7
চমৎকার উত্তর. আমি যদি আসল উদাহরণ কোডটি দেখতে পাই তবে আমি খুশি হব
সুংগুক লিম

18

কেবল একটি খাঁটি সি ++ 98 কাজ চারপাশে ভাগ করে নিতে চেয়েছিলেন:

#include <map>

std::map<std::string, std::string> aka;

struct akaInit
{
    akaInit()
    {
        aka[ "George" ] = "John";
        aka[ "Joe" ] = "Al";
        aka[ "Phil" ] = "Sue";
        aka[ "Smitty" ] = "Yando";
    }
} AkaInit;

2
এটি ডিফল্ট কনস্ট্রাক্টর ছাড়া অবজেক্টের জন্য কাজ করে না, সন্নিবেশ পদ্ধতিটি আইএমএইচওকে অগ্রাধিকার দেওয়া উচিত
আলেসান্দ্রো টেরুজি

16

আপনি চেষ্টা করতে পারেন:

std::map <int, int> mymap = 
{
        std::pair <int, int> (1, 1),
        std::pair <int, int> (2, 2),
        std::pair <int, int> (2, 2)
};

1
আপনি সি ++ 11 এর আগে অ-সমষ্টিগত প্রকারের সাথে আরম্ভকারী তালিকা ব্যবহার করতে পারবেন না, সেক্ষেত্রে আপনি এর {1, 2}পরিবর্তে সংক্ষিপ্ত বাক্য গঠন ব্যবহার করতে পারেন std::pair<int, int>(1, 2)
ফের্রুসিও

9

এটি PierreBdRমানচিত্র অনুলিপি না করে অনুরূপ ।

#include <map>

using namespace std;

bool create_map(map<int,int> &m)
{
  m[1] = 2;
  m[3] = 4;
  m[5] = 6;
  return true;
}

static map<int,int> m;
static bool _dummy = create_map (m);

12
এটি সম্ভবত কোনওভাবেই অনুলিপি করা হত না।
GManNickG

2
কিন্তু এইভাবে মানচিত্র স্থির কনস্টের হতে পারে না, তাই না?
xmoex

6

আপনি যদি সি ++ 98 এর সাথে আটকে থাকেন এবং বুস্টটি ব্যবহার করতে না চান, এখানে স্থিতিশীল মানচিত্রের আরম্ভ করার দরকার হলে আমিই এখানে সমাধান করব solution

typedef std::pair< int, char > elemPair_t;
elemPair_t elemPairs[] = 
{
    elemPair_t( 1, 'a'), 
    elemPair_t( 3, 'b' ), 
    elemPair_t( 5, 'c' ), 
    elemPair_t( 7, 'd' )
};

const std::map< int, char > myMap( &elemPairs[ 0 ], &elemPairs[ sizeof( elemPairs ) / sizeof( elemPairs[ 0 ] ) ] );

-4

আপনার এখানে খুব ভাল উত্তর রয়েছে তবে আমি আমার কাছে এটি "যখন আপনি জানেন সমস্ত হাতুড়ি" এর মতো একটি পরিস্থিতি বলে মনে হচ্ছে ...

স্থির মানচিত্রের সূচনা করার কোনও আদর্শ উপায় কেন নেই তার সহজ উত্তর, কখনও স্থির মানচিত্র ব্যবহার করার কোনও ভাল কারণ নেই ...

মানচিত্র হ'ল একটি কাঠামো যা দ্রুত দেখার জন্য তৈরি করা হয়, অজানা উপাদানগুলির সেট। যদি আপনি হাতগুলির আগে উপাদানগুলি জানেন তবে কেবল একটি সি-অ্যারে ব্যবহার করুন। বাছাই পদ্ধতিতে মানগুলি প্রবেশ করান, বা আপনি যদি এটি না করতে পারেন তবে সেগুলি অনুসারে চালিত করুন। তারপরে আপনি লুপ-আপ এন্ট্রিগুলি, লোয়ার_বাউন্ড / আপার_বাউন্ডে stl :: ফাংশন ব্যবহার করে লগ (এন) পারফরম্যান্স পেতে পারেন। যখন আমি এটি আগে পরীক্ষা করেছি তারা সাধারণত কোনও মানচিত্রের চেয়ে কমপক্ষে 4 গুণ দ্রুত সম্পাদন করে।

সুবিধাগুলি হ'ল ... - দ্রুত পারফরম্যান্স (* 4, আমি অনেকগুলি সিপিইউর প্রকারে পরিমাপ করেছি, এটি সর্বদা 4 এর কাছাকাছি থাকে) - সহজ ডিবাগিং। রৈখিক বিন্যাসে কী চলছে তা দেখা সহজ। - অনুলিপি অপারেশনগুলির তুচ্ছ বাস্তবায়ন, এটি প্রয়োজনীয় হওয়া উচিত। - এটি রান সময়ে কোনও স্মৃতি বরাদ্দ করে না, তাই এটি কখনও ব্যতিক্রম করবে না। - এটি একটি স্ট্যান্ডার্ড ইন্টারফেস, এবং তাই খুব সহজেই ডিএলএল, বা ভাষা ইত্যাদি ভাগ করে নেওয়া যায়

আমি যেতে পারি, তবে আপনি যদি আরও চান, তবে কেন স্ট্রোস্ট্রাপের বিষয়টিতে অনেকগুলি ব্লগ তাকান না।


8
কোনও মানচিত্র ব্যবহারের জন্য পারফরম্যান্সই একমাত্র কারণ নয়। উদাহরণস্বরূপ, অনেকগুলি কেস রয়েছে, যেখানে আপনি মানগুলি একত্রে সংযুক্ত করতে চান (উদাহরণস্বরূপ, একটি ত্রুটির বার্তা সহ একটি ত্রুটি কোড), এবং একটি মানচিত্র ব্যবহার এবং অ্যাক্সেসকে তুলনামূলক সহজ করে তোলে। তবে এই ব্লগ এন্ট্রিগুলির একটি লিঙ্ক আকর্ষণীয় হতে পারে, সম্ভবত আমি কিছু ভুল করছি।
ম্যাথিয়াবিস

5
একটি অ্যারে অনেক সহজ এবং যদি আপনি এটি ব্যবহার করতে পারেন তবে উচ্চতর পারফরম্যান্স রয়েছে। তবে যদি সূচকগুলি (কীগুলি) সামঞ্জস্যপূর্ণ না হয় এবং ব্যাপকভাবে ব্যবধানযুক্ত হয় তবে আপনার একটি মানচিত্রের প্রয়োজন।
কার্লু

1
একটি map(; প্রোগ্রামিং অর্থে, ধরনের কিন্তু, গাণিতিক অর্থে ফাংশন) একটি আংশিক ফাংশন প্রতিনিধিত্বমূলক একটি দরকারী ফর্ম। একটি অ্যারে তা করে না। আপনি বলতে পারবেন না, স্ট্রিং ব্যবহার করে অ্যারে থেকে ডেটা দেখার জন্য।
einpoklum

3
আপনার উত্তরটি বৈধ প্রশ্নের উত্তর দেওয়ার চেষ্টা করে না এবং পরিবর্তে ভাষার সীমাবদ্ধতা সম্পর্কে অনুমান করে বিভিন্ন সমস্যার সমাধানের প্রস্তাব দেয়, তাই ডাউনওয়েট করে। একটি বাস্তব দৃশ্য - পাঠ্য স্ট্রিংয়ে লাইব্রেরির ত্রুটি কোডগুলি ম্যাপিং (ধারাবাহিক বা না)। অ্যারে সহ, অনুসন্ধানের সময়টি হ'ল (এন), যা স্থির ম্যাপিং ও (লগ (এন)) দ্বারা উন্নত করা যেতে পারে।
তোশা

2
যদি সত্যিই "কোনও স্থির মানচিত্র ব্যবহার করার কোনও ভাল কারণ নেই ..." তবে এটি খুব আশ্চর্যের বিষয় যে সিন্ট্যাক্স (ইনিশিয়ালাইজারের তালিকা) যা তাদের ব্যবহার সহজ করে তোলে সি ++ 11 এ যুক্ত করা হয়েছিল।
এলিস্ব্বেবেন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.