আমি কি কোনও রেঞ্জ অপারেশনে অস্থায়ী পাইপ ফিরিয়ে দিতে পারি?


9

ধরুন আমার একটি generate_my_rangeক্লাস রয়েছে যা একটি মডেল করে range(বিশেষত, হয় regular)। তারপরে নিম্নলিখিত কোডটি সঠিক:

auto generate_my_range(int some_param) {    
  auto my_transform_op = [](const auto& x){ return do_sth(x); };
  return my_custom_rng_gen(some_param) | ranges::views::transform(my_transform_op);
}
auto cells = generate_my_range(10) | ranges::to<std::vector>;

হয় my_custom_rng_gen(some_param)(প্রথম) পাইপ অপারেটর দ্বারা মান দ্বারা গৃহীত, অথবা আমি একটি আনত রেফারেন্স আছে একবার আমি চলে generate_my_rangeসুযোগ?

এটি কি ফাংশনাল কলের সাথে একই হবে ranges::views::transform(my_custom_rng_gen(some_param),my_transform_op)?

আমি যদি লভ্যালু রেফারেন্স ব্যবহার করি তবে এটি কি সঠিক হবে? উদাহরণ:

auto generate_my_range(int some_param) {
  auto my_transform_op = [](const auto& x){ return do_sth(x); };
  auto tmp_ref = my_custom_rng_gen(some_param);
  return tmp_ref | ranges::views::transform(my_transform_op);
}

যদি এই ক্রিয়াকলাপগুলির জন্য মানগুলি দ্বারা রেঞ্জ নেওয়া হয়, তবে আমি যদি কোনও পাত্রে কোনও মূল্যবান রেফ পাস করি তবে আমি কী করব? আমার কি কোনও ranges::views::all(my_container)প্যাটার্ন ব্যবহার করা উচিত ?


আমার_কাস্টম_আরং_জেন (কিছু_প্রেম) ইতিমধ্যে আবদ্ধ? আপনি কি Godbolt.org/z/aTF8RN এর মতো কিছু গ্রহণ না করে (5)?
Porsche9II

@ Porsche9II হ্যাঁ এটি একটি সীমাবদ্ধ পরিসর। ধরা যাক এটি একটি ধারক
বেরেঞ্জার ২

উত্তর:


4

রেঞ্জ লাইব্রেরিতে দুটি ধরণের অপারেশন রয়েছে:

  • যা অলস এবং অন্তর্নিহিত ধারকটির অস্তিত্ব দরকার তা দেখায়
  • ক্রিয়া যা উত্সাহী, এবং ফলস্বরূপ নতুন পাত্রে উত্পাদন করে (বা বিদ্যমানগুলি সংশোধন করুন)

দর্শনগুলি হালকা ওজনের। আপনি এগুলি মান দ্বারা পাস করেন এবং অন্তর্নিহিত পাত্রে বৈধ এবং অপরিবর্তিত থাকা প্রয়োজন।

থেকে রেঞ্জ-V3 ডকুমেন্টেশন

একটি ভিউ হ'ল লাইটওয়েটের মোড়ক যা কোনও পরিবর্তন বা অনুলিপি ছাড়াই কিছু কাস্টম পদ্ধতিতে উপাদানগুলির অন্তর্নিহিত ক্রমের একটি দৃশ্য উপস্থাপন করে। ভিউগুলি তৈরি এবং অনুলিপি করার পক্ষে সস্তা এবং অ-মালিকানা সংক্রান্ত রেফারেন্স শব্দার্থক শব্দ রয়েছে।

এবং:

অন্তর্নিহিত রেঞ্জের যে কোনও ক্রিয়াকলাপ যা তার পুনরাবৃত্তকারী বা প্রেরণকারীকে অবৈধ করে দেয় সেই ব্যাপ্তিকে যে সীমার কোনও অংশ উল্লেখ করে তা অবৈধ করে দেবে।

অন্তর্নিহিত ধারকটির ধ্বংসটি অবশ্যই এটিতে সমস্ত পুনরাবৃত্তিকারীকে অবৈধ করে দেয়।

আপনার কোডে আপনি স্পষ্টত দর্শন ব্যবহার করছেন - আপনি ব্যবহার করেন ranges::views::transform। পাইপটি কেবল একটি সিনট্যাকটিক চিনি যা এটির মতো লেখাকে সহজ করে তোলে। আপনি কী উত্পাদন করেন তা দেখতে পাইপের শেষ জিনিসটি দেখতে হবে - আপনার ক্ষেত্রে এটি একটি দৃশ্য।

যদি কোনও পাইপ অপারেটর না থাকে তবে সম্ভবত এটির মতো দেখতে লাগবে:

ranges::views::transform(my_custom_rng_gen(some_param), my_transform_op)

যদি সেখানে একাধিক রূপান্তর সংযুক্ত থাকে তবে আপনি দেখতে পাচ্ছেন যে এটি কতটা কুৎসিত হবে।

সুতরাং, যদি my_custom_rng_genকোনও ধারক উত্পাদন করে, যা আপনি রূপান্তর করেন এবং তারপরে ফিরে আসেন, সেই ধারকটি ধ্বংস হয়ে যায় এবং আপনার দৃষ্টিভঙ্গি থেকে আপনার ঝুঁকির উল্লেখ রয়েছে। যদি my_custom_rng_genএই স্কোপের বাইরে থাকা কোনও ধারকের কাছে অন্য মতামত হয় তবে সবকিছু ঠিক আছে।

যাইহোক, সংকলকটি সনাক্ত করতে সক্ষম হবে যে আপনি একটি অস্থায়ী ধারকটিতে একটি ভিউ প্রয়োগ করছেন এবং আপনাকে একটি সংকলন ত্রুটির সাথে আঘাত করবে।

যদি আপনি চান যে আপনার ফাংশনটি কোনও ধারক হিসাবে কোনও পরিসীমা ফেরত আসতে পারে, তবে আপনাকে ফলাফলটি স্পষ্টতই "বাস্তবায়ন" করতে হবে। তার জন্য, ranges::toফাংশনের মধ্যে অপারেটরটি ব্যবহার করুন ।


আপডেট: আপনার মন্তব্যের বিষয়ে আরও স্পষ্ট হয়ে উঠতে "ডকুমেন্টেশনটি কোথায় বলে যে র‌্যাংক / পাইপিং রঞ্জকটি কোনও ভিউ নেয় এবং সঞ্চয় করে?"

পাইপ হ'ল সহজেই পঠনযোগ্য সহজে প্রকাশের সাথে জিনিসগুলিকে সংযুক্ত করার জন্য একটি সিনট্যাকটিক চিনি। এটি কীভাবে ব্যবহৃত হবে তার উপর নির্ভর করে এটি কোনও দর্শন ফিরে আসতে পারে এবং নাও পারে। এটি ডান হাতের যুক্তির উপর নির্ভর করে। আপনার ক্ষেত্রে এটি হয়:

`<some range> | ranges::views::transform(...)`

সুতরাং এক্সপ্রেশনটি যা কিছু views::transformফেরত দেয়।

এখন, রূপান্তরটির ডকুমেন্টেশন পড়ে:

নীচে রেঞ্জ-ভি 3 সরবরাহ করে এমন অলস পরিসীমা সংযোজকগুলির বা ভিউগুলির একটি তালিকা এবং প্রতিটি কীভাবে ব্যবহার করার উদ্দেশ্যে রয়েছে সে সম্পর্কে একটি ব্লার্ব রয়েছে।

[...]

views::transform

একটি উত্স পরিসীমা এবং একটি unary ফাংশন দেওয়া, একটি নতুন পরিসীমা ফিরে যেখানে প্রতিটি ফলাফল উপাদান একটি উত্স উপাদান এ unary ফাংশন প্রয়োগ ফলাফল।

সুতরাং এটি একটি সীমার ফিরিয়ে দেওয়া উচিত তবে যেহেতু এটি একটি অলস অপারেটর, যে সীমার এটা ফেরৎ হয় একটি দৃশ্য, তার সব শব্দার্থবিদ্যা সঙ্গে।


ঠিক আছে. আমার কাছে এখনও কিছুটা রহস্যজনক যে আমি পাইপটিতে কোনও কনটেইনার পাস করার সময় এটি কীভাবে কাজ করে (যেমন রচনা দ্বারা নির্মিত রেঞ্জ অবজেক্ট)। এটি কোনওভাবে ধারকটির ভিউ সঞ্চয় করতে হবে। এটা দিয়ে কি হয় ranges::views::all(my_container)? এবং যদি কোনও ভিউ পাইপে চলে যায়? এটি কি কনটেইনার বা একটি দর্শন পাস করার বিষয়টি স্বীকৃতি দেয়? এটা কি দরকার? কিভাবে?
বেরেঞ্জার

"সংকলকটি বুঝতে সক্ষম হওয়া উচিত যে আপনি একটি অস্থায়ী ধারকটিতে একটি ভিউ প্রয়োগ করছেন এবং আপনাকে একটি সংকলন ত্রুটির সাথে আঘাত করতে হবে" এটি আমিও ভেবেছিলাম: আমি যদি বোকা কিছু করি তবে এর অর্থ এই ধরণের চুক্তি (বাম হওয়া) মান) পূরণ হয় না। এর মতো স্টাফ রেঞ্জ-ভি 3 দ্বারা সম্পন্ন হয়। তবে এক্ষেত্রে অবশ্যই কোনও সমস্যা নেই। এটি সংকলন এবং রান। সুতরাং অপরিবর্তিত আচরণ থাকতে পারে তবে এটি প্রদর্শিত হয় না।
বেরেঞ্জার

আপনার কোডটি দুর্ঘটনাক্রমে সঠিকভাবে চালিত হয়েছে বা সবকিছু ঠিক আছে কিনা তা নিশ্চিত হওয়ার জন্য আমার লিখিত সামগ্রীগুলি দেখতে হবে my_custom_rng_gentransformহুডের নীচে পাইপ এবং কীভাবে ইন্টারেক্ট হয় তা গুরুত্বপূর্ণ নয় is পুরো অভিব্যক্তিটি একটি আর্গুমেন্ট হিসাবে একটি পরিসর নেয় (কোনও ধারক বা কোনও ধারক হিসাবে দেখায়) এবং সেই ধারকটিতে একটি ভিন্ন দৃশ্য প্রদান করে। রিটার্ন মান কখনই ধারকটির মালিক হবে না, কারণ এটি একটি দর্শন।
CygnusX1

1

রেঞ্জ-ভি 3 ডকুমেন্টেশন থেকে নেওয়া :

ভিউ [...] এর মালিকানাবিহীন রেফারেন্স শব্দার্থবিদ্যা রয়েছে।

এবং

একটি একক পরিসীমা অবজেক্ট থাকা অপারেশনগুলির পাইপলাইনের অনুমতি দেয়। একটি পাইপলাইনে, একটি পরিসীমা অলসভাবে কোনওভাবে অভিযোজিত হয় বা আগ্রহের সাথে পরিবর্তিত হয়, ফলটি আরও অভিযোজন বা মিউটেশনের জন্য অবিলম্বে উপলব্ধ available অলস অভিযোজন দর্শন দ্বারা পরিচালিত হয়, এবং আগ্রহী রূপান্তর কর্ম দ্বারা পরিচালিত হয়।

// taken directly from the the ranges documentation
std::vector<int> const vi{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
using namespace ranges;
auto rng = vi | views::remove_if([](int i){ return i % 2 == 1; })
              | views::transform([](int i){ return std::to_string(i); });
// rng == {"2","4","6","8","10"};

উপরের কোডে, rng কেবল অন্তর্নিহিত ডেটা এবং ফিল্টার এবং রূপান্তর ফাংশনগুলির একটি রেফারেন্স সঞ্চয় করে। আরএনজি পুনরাবৃত্তি না করা পর্যন্ত কোনও কাজ করা হয় না।

যেহেতু আপনি বলেছিলেন যে অস্থায়ী পরিসরটি একটি ধারক হিসাবে বিবেচনা করা যেতে পারে, তাই আপনার ক্রিয়াকলাপটি ঝুঁকির রেফারেন্স দেয়।

অন্য কথায়, আপনাকে নিশ্চিত করতে হবে যে অন্তর্নিহিত পরিসরটি দৃশ্যকে বহিরাগত করেছে বা আপনি সমস্যায় পড়েছেন।


হ্যাঁ, দর্শনগুলি মালিকানার নয়, তবে ডকুমেন্টেশনটি কোথায় বলেছে যে রঞ্জক / পাইপিং রঞ্জকটি কোনও ভিউ নেয় এবং সঞ্চয় করে? নিম্নলিখিত নীতিটি পাওয়া সম্ভব হবে (এবং আমি মনে করি, একটি ভাল জিনিস): মানটি যদি সঞ্চারিত রেফালিউর রেফারেন্স দ্বারা দেওয়া হয় তবে মান দ্বারা সঞ্চয় করুন।
বেরঞ্জার

1
@ বেরেঞ্জার রেঞ্জের ডকুমেন্টেশন থেকে আমি আরও কিছু যুক্ত করেছি। তবে মূল কথাটি হ'ল: একটি ভিউ অ-মালিকানাধীন । আপনি এটি কোনও মূল্যের হাত দিয়েছেন কিনা তা বিবেচ্য নয়।
রুম্বুরাক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.