কিভাবে স্ট্যান্ড :: মানচিত্রের () লুপের জন্য পরিসর-ভিত্তিক ব্যবহার করবেন?


336

() লুপগুলির জন্য সি ++ 11 রেঞ্জ-ভিত্তিকের সাধারণ উদাহরণ হ'ল সর্বদা সহজ কিছু:

std::vector<int> numbers = { 1, 2, 3, 4, 5, 6, 7 };
for ( auto xyz : numbers )
{
     std::cout << xyz << std::endl;
}

কোন ক্ষেত্রে xyzএকটি int। কিন্তু, যখন আমাদের মানচিত্রের মতো কিছু থাকে তখন কী হয়? এই উদাহরণে ভেরিয়েবলের প্রকারটি কী:

std::map< foo, bar > testing = { /*...blah...*/ };
for ( auto abc : testing )
{
    std::cout << abc << std::endl;         // ? should this give a foo? a bar?
    std::cout << abc->first << std::endl;  // ? or is abc an iterator?
}

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

মানচিত্র এবং মাল্টিম্যাপের মতো জিনিসগুলি যখন আসে তখন আমি কী আশা করব তা নিয়ে আমি বিভ্রান্ত।

(আমি এখনও জি ++ ৪.৪ এ রয়েছি, যদিও পরিসীমা-ভিত্তিক লুপগুলি জি ++ ৪.+++ এ রয়েছে, সুতরাং এখনও এটি চেষ্টা করার সুযোগ পাইনি have)


4
স্টেটমেন্টের ব্যাপ্তি একই নামের অধীনে স্ট্যান্ডার্ড লাইব্রেরি std::beginএবং std::endফাংশন বা সদস্য ফাংশন সহ একটি অপরিষ্কার নাচ করে ।
জিন বুশুয়েভ

10
@ উইল 3 লাইনের উদাহরণে আপনি কী ভুয়া ভেরিয়েবলের নাম ধরে ফেলছেন?
স্টাফেন

উত্তর:


495

ধারক প্রতিটি উপাদান একটি হল map<K, V>::value_typeযা হয়, typedefজন্য std::pair<const K, V>। ফলস্বরূপ, সি ++ 17 বা তারও বেশিতে, আপনি লিখতে পারেন

for (auto& [key, value]: myMap) {
    std::cout << key << " has value " << value << std::endl;
}

বা হিসাবে

for (const auto& [key, value]: myMap) {
    std::cout << key << " has value " << value << std::endl;
}

আপনি যদি মানগুলি পরিবর্তন করার পরিকল্পনা না করেন।

সি ++ 11 এবং সি ++ 14 এ আপনি forপ্রতিটি জুড়াকে নিজস্ব থেকে বের করার জন্য বর্ধিত লুপগুলি ব্যবহার করতে পারেন , তারপরে কী এবং মানগুলি ম্যানুয়ালি বের করুন:

for (const auto& kv : myMap) {
    std::cout << kv.first << " has value " << kv.second << std::endl;
}

আপনি যদি মানগুলির কেবল পঠনযোগ্য দর্শন চান তবে আপনি kvভেরিয়েবলটিকে চিহ্নিত করার বিষয়টিও বিবেচনা constকরতে পারেন।


95

সি ++ 17 এ একে স্ট্রাকচার্ড বাইন্ডিংস বলা হয় , যা নিম্নলিখিতগুলির জন্য অনুমতি দেয়:

std::map< foo, bar > testing = { /*...blah...*/ };
for ( const auto& [ k, v ] : testing )
{
  std::cout << k << "=" << v << "\n";
}

কীটিতে কী পাওয়া সম্ভব const &, তবে মানটির ক্ষেত্রে একটি নিরবচ্ছিন্ন রেফারেন্স? (কারণ এটি ম্যাপ :: মান_প্রকারটি কি করে ...)
পিটারচেন

2
@peterchen: kহয় constযদি আপনি ব্যবহারfor(auto&[k,v]:testing)
টালি

1
কাঠামোবদ্ধ বাইন্ডিং উপর cpppreference en.cppreference.com/w/cpp/language/structured_binding
TankorSmash

আপনি যদি জিসিসির সাথে সংকলন করেন তবে আপনার কাঠামোগত বাইন্ডিংয়ের জন্য 7 বা তার বেশি সংস্করণ প্রয়োজন: gcc.gnu.org/projects/cxx-status.html
csknk

25

এই কাগজ থেকে: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2049.pdf

for( type-specifier-seq simple-declarator : expression ) statement

সিনথেটিক্যালি এর সমতুল্য

{
    typedef decltype(expression) C;
    auto&& rng(expression);
    for (auto begin(std::For<C>::begin(rng)), end(std::For<C>::end(rng)); begin != end; ++ begin) {
        type-specier-seq simple-declarator(*begin);
        statement
    }
}

সুতরাং আপনি পরিষ্কারভাবে দেখতে পারেন যে abcআপনার ক্ষেত্রে যা আছে তা হবে std::pair<key_type, value_type >। সুতরাং মুদ্রণ আপনি এক্সেস প্রতিটি উপাদান কি করতে পারেন জন্য abc.firstএবংabc.second


15

আপনি যদি কেবল নিজের মানচিত্র থেকে কীগুলি / মানগুলি দেখতে চান এবং বুস্ট ব্যবহার করতে চান তবে আপনি পরিসর ভিত্তিক লুপগুলি সহ বুস্ট অ্যাডাপ্টার ব্যবহার করতে পারেন:

for (const auto& value : myMap | boost::adaptors::map_values)
{
    std::cout << value << std::endl;
}

সমতুল্য বুস্ট :: অ্যাডাপ্টার :: কী_ভ্যালু রয়েছে

http://www.boost.org/doc/libs/1_51_0/libs/range/doc/html/range/reference/adaptors/reference/map_values.html


3

যদি foo এবং বারের অনুলিপি অপারেটরটি সস্তা হয় (যেমন, int, চর, পয়েন্টার ইত্যাদি), আপনি নিম্নলিখিতটি করতে পারেন:

foo f; bar b;
BOOST_FOREACH(boost::tie(f,b),testing)
{
  cout << "Foo is " << f << " Bar is " << b;
}

4
কোডের প্রথম স্নিপেট একটি "C ++ 11 রেঞ্জ-ভিত্তিক ()" ব্যবহার করছে না। এটি "সি ++ 11: এর কোনও উত্তর নয়: কীভাবে স্ট্যান্ড :: মানচিত্রের () লুপের জন্য পরিসর-ভিত্তিক ব্যবহার করবেন?"
আইসোফোন

1
@ytj উত্তরে এটি ইতিমধ্যে উল্লেখ করা হয়েছে যে এটি কাজ করে না। আমি এটিকে সরাতে চাই না যাতে নতুন ব্যবহারকারীদের চেষ্টা করে দেখতে না পারা এবং আবার সত্যতা খুঁজে বার করতে হবে।
বালকি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.