সি + ডাব্লু :: সি ++ 11 এ স্ট্রিং বাস্তবায়ন বৈধতা


117

এটা আমার বুঝতে ছিল যে অনুলিপি-অন-লিখনটি std::stringসি ++ 11-এর সাথে সামঞ্জস্য করার কার্যকর উপায় নয় , তবে সম্প্রতি যখন এটি আলোচনায় এসেছিল তখন আমি নিজেকে সরাসরি উক্ত বক্তব্যকে সমর্থন করতে অক্ষম দেখলাম।

আমি কি ঠিক করছি যে সি ++ 11 এর COW ভিত্তিক বাস্তবায়ন স্বীকার করে না std::string?

যদি তা হয় তবে এই সীমাবদ্ধতাটি নতুন মান (কোথায়) কোথাও স্পষ্টভাবে বলা হয়েছে?

বা এই বিধিনিষেধটি বোঝানো হয়েছে, এই অর্থে যে এটি কোনও নতুন প্রয়োজনের সংযুক্ত প্রভাব std::stringযা কোনও COW ভিত্তিক বাস্তবায়নকে বাধা দেয় std::string। এই ক্ষেত্রে, আমি একটি অধ্যায় এবং 'সি ++ 11 এর শৈলী শৈলীর উত্স সম্পর্কে আগ্রহী, কার্যকরভাবে COW ভিত্তিক std::stringবাস্তবায়ন নিষিদ্ধ '।


5
তাদের COW স্ট্রিংয়ের জন্য জিসিসি বাগটি gcc.gnu.org/bugzilla/show_bug.cgi?id=21334#c45 । Libstdc ++ তে স্ট্যান্ড :: স্ট্রিংয়ের একটি নতুন সি ++ 11 সংকলন বাস্তবায়ন ট্র্যাক করা বাগগুলির মধ্যে একটি হ'ল gcc.gnu.org/bugzilla/show_bug.cgi?id=53221
ব্যবহারকারী 7610

উত্তর:


120

এটি অনুমোদিত নয়, কারণ মান 21.4.1 পি 6 অনুযায়ী পুনরাবৃত্তি / রেফারেন্সগুলির অবৈধকরণ কেবলমাত্র এর জন্য অনুমোদিত

- আর্গুমেন্ট হিসাবে নন-কনস্ট্যান্ট বেসিক_স্ট্রিংয়ের রেফারেন্স গ্রহণ করে কোনও স্ট্যান্ডার্ড লাইব্রেরি ফাংশনের যুক্তি হিসাবে।

- অপারেটর []] এর সামনে, পিছনে, পিছনে শুরু করুন, রিবেগিন করুন, শেষ করুন এবং উপস্থাপনা ব্যতীত নন-কনস্ট্যান্ড সদস্য ফাংশনগুলি কল করা হচ্ছে।

একটি COW স্ট্রিংয়ের জন্য, নন-কনস্টের operator[]সাথে কল করার জন্য একটি অনুলিপি তৈরি করতে হবে (এবং রেফারেন্সকে অবৈধ করে দেবে), যা উপরের অনুচ্ছেদে অনুমোদিত নয়। সুতরাং, সি ++ 11 এ কোনও COW স্ট্রিং থাকা বৈধ নয়।


4
কিছু যুক্তি: N2534
এমএম

8
-1 যুক্তি জল ধরে না। একটি COW অনুলিপি করার সময় কোনও রেফারেন্স বা পুনরাবৃত্তিযোগ্য যা অকার্যকর হতে পারে, অনুলিপি করার সম্পূর্ণ পয়েন্টটি হ'ল এই জাতীয় রেফারেন্স বা পুনরুক্তিগুলি এখন প্রাপ্ত করা হচ্ছে, সুতরাং অনুলিপি করা প্রয়োজনীয়। তবে এটি এখনও হতে পারে যে সি ++ 11 COW বাস্তবায়নকে অস্বীকার করে।
চিয়ার্স এবং এইচটিএইচ - Alf

11
@ চিয়ারসান্থ.-আলফ: যৌক্তিকতাটি COW অনুমোদিত হলে নিম্নলিখিতটিতে যুক্তিটি দেখা যাবে: সি 1 এর std::string a("something"); char& c1 = a[0]; std::string b(a); char& c2 = a[1]; একটি রেফারেন্স। আপনি তখন "কপি" ক। তারপরে, আপনি যখন দ্বিতীয়বার রেফারেন্সটি নেওয়ার চেষ্টা করবেন তখন একই বাফারকে নির্দেশ করে এমন দুটি স্ট্রিং রয়েছে বলে নন-কনস্ট্যান্ট রেফারেন্স পেতে একটি অনুলিপি তৈরি করতে হবে। এটি নেওয়া প্রথম রেফারেন্সটি বাতিল করতে হবে এবং এটি উপরে বর্ণিত বিভাগের বিরুদ্ধে।
ডেভ এস

9
@ Cheersandhth.-আলফ অনুযায়ী এই , অন্তত জিসিসি বলদ বাস্তবায়ন নেই না DaveS ঠিক কি বলছে। সুতরাং কমপক্ষে COW এর স্টাইলটি মান দ্বারা নিষিদ্ধ।
তাভিয়ান বার্নেস

4
@ অ্যালফ: এই উত্তরে যুক্তি দেওয়া হয়েছে যে অবিচ্ছিন্ন operator[](1) অবশ্যই একটি অনুলিপি তৈরি করতে হবে এবং এটি (2) এটি করা অবৈধ। এই দুটি বিষয়গুলির মধ্যে কোনটির সাথে আপনি একমত নন? আপনার প্রথম মন্তব্যটির দিকে তাকিয়ে দেখে মনে হচ্ছে যে কোনও বাস্তবায়ন অ্যাক্সেস না হওয়া অবধি কমপক্ষে এই প্রয়োজনীয়তার অধীনে স্ট্রিং ভাগ করতে পারে, তবে পড়ার এবং লেখার জন্য উভয়ই এটিকে ভাগ করে নেওয়া প্রয়োজন। এটা কি আপনার যুক্তি?
বেন ভয়েগট

48

ডেভ এস এবং gbjbaanb এর উত্তরগুলি সঠিক । (এবং লাক ড্যান্টনের বিষয়টিও সঠিক, যদিও এটি আসল নিয়মটি নিষিদ্ধ করার চেয়ে বরং COW স্ট্রিং নিষিদ্ধ করার আরও বেশি পার্শ্ব-প্রতিক্রিয়া।)

তবে কিছু বিভ্রান্তি দূর করতে আমি আরও কিছু যুক্তি যুক্ত করতে যাচ্ছি। জিসিসি বাগজিলায় আমার মন্তব্যের সাথে বিভিন্ন মন্তব্য লিঙ্ক রয়েছে যা নিম্নলিখিত উদাহরণটি দেয়:

std::string s("str");
const char* p = s.data();
{
    std::string s2(s);
    (void) s[0];
}
std::cout << *p << '\n';  // p is dangling

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

জিসিসি পুরাতন রেফারেন্স-গণনা ব্যবহার std::stringপ্রয়োগ, যে কোড কারণ অনির্ধারিত আচরণ আছে, p হয় অকার্যকর ও বাতিল, একটি আনত পয়েন্টার হয়ে উঠছে। (যা ঘটে তা হ'ল এটি s2নির্মাণের সাথে সাথে ডেটা ভাগ করে s, তবে অ-কনস্ট্যান্ট রেফারেন্সের মাধ্যমে s[0]ডেটা ভাগ করা প্রয়োজন, সুতরাং sএকটি "লিখিত অনুলিপি" থাকে কারণ রেফারেন্সটি s[0]সম্ভবত লেখার জন্য ব্যবহৃত হতে পারে s, তারপরে s2যায় সুযোগ ছাড়াই, নির্দেশিত অ্যারে ধ্বংস করে p)।

সি ++ 03 স্ট্যান্ডার্ডটি স্পষ্টভাবে 21.3 [lib.basic.string] পি 5-তে সেই আচরণের অনুমতি দেয় যেখানে এটি বলে যে data()প্রথম কলটিতে কল করার পরে operator[]()পয়েন্টার, রেফারেন্স এবং পুনরাবৃত্তিকে অবৈধ করতে পারে। সুতরাং জিসিসির COW স্ট্রিংটি একটি বৈধ সি ++ 03 বাস্তবায়ন ছিল।

সি ++ 11 স্ট্যান্ডার্ড আর সেই আচরণের অনুমতি দেয় না , কারণ কোনও কল operator[]()পয়েন্টার, রেফারেন্স বা পুনরুক্তিকারীকে অকার্যকর করতে পারে, তারা কলটি অনুসরণ করে কিনা তা নির্বিশেষে data()

সুতরাং উপরের উদাহরণটি অবশ্যই C ++ 11 এ কাজ করবে, তবে libstdc ++ এর ধরণের COW স্ট্রিংয়ের সাথে কাজ করে না , সুতরাং C ++ 11 এ ধরণের COW স্ট্রিংয়ের অনুমতি নেই।


3
একটি বাস্তবায়ন যা কলটিতে অংশীদারি করে .data()(এবং পয়েন্টার, রেফারেন্স, বা পুনরুক্তির প্রতিটি প্রত্যাবর্তনে) সেই সমস্যায় ভোগে না। অর্থাত্ (আক্রমণকারী) কোনও বাফার যেকোন সময় শেয়ারড হয় না অন্যথায় কোনও বাহ্যিক রেফের সাথে ভাগ করা হয়। আমি ভেবেছিলাম আপনি এই উদাহরণটি সম্পর্কে মন্তব্যটি একটি অনানুষ্ঠানিক বাগ রিপোর্ট-হিসাবে-মন্তব্য হিসাবে মন্তব্য করেছেন, এটির ভুল বোঝার জন্য অত্যন্ত দুঃখিত! আমি যেমন এখানে বর্ণনা করেছি তেমন বাস্তবায়ন বিবেচনা করে আপনি দেখতে পাচ্ছেন, যা সি ++ 11 এ জরিমানা কাজ করে যখন noexceptপ্রয়োজনীয়তাগুলি উপেক্ষা করা হয়, উদাহরণটি আনুষ্ঠানিক সম্পর্কে কিছু না বলে। আপনি চাইলে আমি কোড সরবরাহ করতে পারি।
চিয়ার্স এবং এইচটিএইচ - আলফ

7
আপনি যদি স্ট্রিংয়ের প্রায় প্রতিটি অ্যাক্সেস ভাগ করে না নেন তবে আপনি ভাগ করে নেওয়ার সমস্ত সুবিধা হারাবেন। স্ট্যান্ডার্ড লাইব্রেরি হিসাবে এটি ব্যবহার করে বিরক্ত করার জন্য একটি COW বাস্তবায়ন ব্যবহারিক হতে হবে std::stringএবং আমি আন্তরিকভাবে সন্দেহ করি যে আপনি একটি দরকারী, পারফরম্যান্ট COW স্ট্রিং প্রদর্শন করতে পারেন যা সি ++ 11 অবৈধকরণের প্রয়োজনীয়তা পূরণ করে। সুতরাং আমি বজায় রেখেছি যে noexceptশেষ মুহুর্তে যুক্ত হওয়া স্পেসিফিকেশনগুলি অন্তর্নিহিত কারণ নয়, COW স্ট্রিং নিষিদ্ধ করার ফলাফল। N2668 পুরোপুরি পরিষ্কার বলে মনে হচ্ছে, আপনি কেন কমিটির পরিকল্পনার সুস্পষ্ট প্রমাণগুলি অস্বীকার করে চলেছেন?
জোনাথন ওয়াকলি

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

2
সবেমাত্র কিছু কোড একসাথে কোবলিং করে এখন আমি আবিষ্কার করেছি যে এখানে রয়েছে 129 basic_stringসদস্যের কার্যকারিতা, নিখরচায় ফাংশন। বিমূর্তকরণ ব্যয়: এই অফ-দ্য-কফ অ-অপটিমাইজড তাজা জিরোথ সংস্করণ কোডটি জি ++ এবং এমএসভিসি উভয়ের সাথেই 50 থেকে 100% ধীর। এটি থ্রেড সুরক্ষা করে না (যথেষ্ট সহজ উপকার shared_ptr, খুব সহজেই আমি মনে করি) এবং সময়সীকরণের উদ্দেশ্যে ডিকশনারি বাছাই করার পক্ষে এটি যথেষ্ট পর্যাপ্ত, তবে মডুলো বাগগুলি basic_stringসি ++ noexceptপ্রয়োজনীয়তা ব্যতীত একটি রেফারেন্স অনুমোদিত বলে প্রমাণিত হয়েছে point github.com/alfps/In-pr اصولle
চিয়ার্স এবং এইচটিএইচ। - আলফ


20

এটি হ'ল, দ্রুততর স্ট্রিংগুলি তৈরি করার জন্য কউ একটি গ্রহণযোগ্য প্রক্রিয়া ... তবে ...

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

অন্য কারণগুলি হ'ল []অপারেটর অপরিবর্তিত হওয়ার প্রত্যাশা করে কোনও স্ট্রিং ওভাররাইট করার জন্য কোনও সুরক্ষা ছাড়াই অপারেটর আপনাকে স্ট্রিং ডেটা ফিরিয়ে দেবে। একই প্রযোজ্য c_str()এবং data()

কুইক গুগল বলেছে যে মাল্টিথ্রেডিং মূলত এটি কার্যকরভাবে অনুমোদিত নয় (স্পষ্টভাবে নয়)।

প্রস্তাবে বলা হয়েছে:

প্রস্তাব

আমরা সমস্ত পুনরাবৃত্তিকারী এবং উপাদান অ্যাক্সেস ক্রিয়াকলাপ নিরাপদে যুগপত সম্পাদনযোগ্য করার প্রস্তাব দিই।

সিক্যুয়াল কোডেও আমরা ক্রিয়াকলাপের স্থায়িত্ব বৃদ্ধি করছি।

এই পরিবর্তনটি কার্যকরভাবে অনুলিপি-অনুলিপি প্রয়োগগুলি বাতিল করে।

অনুসরণ করেছে

অনুলিপি-অন-লেখার প্রয়োগগুলি থেকে স্যুইচ করার কারণে কর্মক্ষমতাটির সবচেয়ে বড় সম্ভাব্য ক্ষতি হ'ল খুব বড় পঠনযোগ্য স্ট্রিং সহ অ্যাপ্লিকেশনগুলির মেমরির বৃদ্ধি। তবে আমরা বিশ্বাস করি যে এই অ্যাপ্লিকেশনগুলির জন্য দড়িগুলি আরও ভাল প্রযুক্তিগত সমাধান এবং লাইব্রেরি টিআর 2-র অন্তর্ভুক্তির জন্য দড়ির প্রস্তাব বিবেচনা করার পরামর্শ দেয়।

দড়াদড়ি STLPort এবং SGIs STL অংশ।


2
অপারেটর [] সমস্যাটি আসলেই কোনও সমস্যা নয়। কনস্ট কনটেন্টটি সুরক্ষা সরবরাহ করে এবং অ-কনস্ট্যান্ট বৈকল্পিকের কাছে সর্বদা সেই সময়ে কো করা (বা সত্যই পাগল হওয়া এবং এটি ট্রিগার করার জন্য একটি পৃষ্ঠা ত্রুটি স্থাপন করা) বিকল্প রয়েছে।
ক্রিস্টোফার স্মিথ

+1 বিষয়গুলিতে যায়।
চিয়ার্স এবং এইচটিএইচ - Alf

5
এটি কেবল নির্বোধ যে একটি স্ট্যান্ড :: গাভুলি স্ট্রিং ক্লাসটি লক_বাফার () ইত্যাদি সহ অন্তর্ভুক্ত ছিল না, এমন অনেক সময় আছে যা আমি জানি থ্রেডিং কোনও সমস্যা নয়। আরো প্রায়ই না আসলে, আসলে।
এরিক অ্যারোনস্টি

আমি একটি বিকল্প পরামর্শ, আইগ দড়ি পছন্দ। আমি বিস্মিত যদি অন্য কোন বিকল্প ধরণের এবং বাস্তবায়ন উপলব্ধ আছে।
ভোল্টায়ার

5

21.4.2 বেসিক_স্ট্রিং কনস্ট্রাক্টর এবং অ্যাসাইনমেন্ট অপারেটরগুলি [স্ট্রিংকনস]

basic_string(const basic_string<charT,traits,Allocator>& str);

[...]

2 প্রভাব : basic_stringসারণী in৪ তে উল্লিখিত হিসাবে শ্রেণীর একটি অবজেক্ট তৈরি করে [[...]

সারণী help৪ সহায়কভাবে নথি করে যা এই (অনুলিপি) কনস্ট্রাক্টরের মাধ্যমে কোনও বস্তু তৈরির পরে this->data()মূল্য হিসাবে রয়েছে:

অ্যারের বরাদ্দকৃত অনুলিপিটির প্রথম উপাদানের বিন্দুতে যার প্রথম উপাদানটি str.data দ্বারা চিহ্নিত করা হয় ()

অন্যান্য অনুরূপ নির্মাতাদের জন্য অনুরূপ প্রয়োজনীয়তা রয়েছে।


+1 টি কীভাবে সি ++ 11 (অন্তত আংশিকভাবে) কাউ নিষিদ্ধ করে।
চিয়ার্স এবং এইচটিএইচ - Alf

দুঃখিত, আমি ক্লান্ত ছিলাম। এটি ছাড়া আর কিছুই ব্যাখ্যা করে না। তবুও এটি দরকারী তথ্য তাই আমি উঁচুতে দাঁড়াতে দেব।
চিয়ার্স এবং এইচটিএইচ - Alf

1

যেহেতু এখন এটি গ্যারান্টিযুক্ত যে স্ট্রিংগুলি স্বচ্ছভাবে সংরক্ষণ করা হয় এবং আপনাকে এখন একটি স্ট্রিংয়ের অভ্যন্তরীণ স্টোরেজটিতে পয়েন্টার নেওয়ার অনুমতি দেওয়া হয়, (উদাহরণস্বরূপ & str [0] এটি অ্যারের মতো করে কাজ করে), এটি একটি দরকারী COW তৈরি করা সম্ভব নয় বাস্তবায়ন. অনেক বেশি কিছু করার জন্য আপনাকে একটি অনুলিপি তৈরি করতে হবে। এমনকি কেবল ব্যবহার operator[]বা begin()অন-কনস্ট্রিং স্ট্রিংয়ের জন্য একটি অনুলিপি প্রয়োজন।


1
আমি মনে করি সি ++ 11 এর স্ট্রিংগুলি স্বচ্ছভাবে সংরক্ষণ করার গ্যারান্টিযুক্ত।
এমফোঁটানিনি

4
অতীতে আপনাকে সেই সমস্ত পরিস্থিতিতে অনুলিপিগুলি করতে হয়েছিল এবং এটি কোনও সমস্যা ছিল না ...
ডেভিড রদ্রিগেজ - ড্রিবিস

@ এমফন্টানিনি হ্যাঁ, তবে তারা আগে ছিল না
ডার্ক হলসোপল

3
যদিও সি ++ 11 এর গ্যারান্টিযুক্ত স্ট্রিংগুলি সংগত, এটি COW স্ট্রিং নিষিদ্ধ করার জন্য অরথগোনাল। জিসিসির সিওডাব্লু স্ট্রিংটি সামঞ্জস্যপূর্ণ, সুতরাং আপনার দাবিটি পরিষ্কার যে "একটি দরকারী COW বাস্তবায়ন করা সম্ভব নয়" বোগাস us
জোনাথন ওয়েকেলি

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

1

basic_stringসি ++ 11 এবং তারপরে COW নিষিদ্ধ?

সংক্রান্ত

আমি কি ঠিক করছি যে সি ++ 11 এর COW ভিত্তিক বাস্তবায়ন স্বীকার করে না std::string?

হ্যাঁ.

সংক্রান্ত

যদি তা হয় তবে এই সীমাবদ্ধতাটি নতুন মান (কোথায়) কোথাও স্পষ্টভাবে বলা হয়েছে?

প্রায় প্রত্যক্ষভাবে, বেশ কয়েকটি ক্রিয়াকলাপের জন্য ধ্রুবক জটিলতার প্রয়োজনীয়তার জন্য যাকোনও COW বাস্তবায়নে স্ট্রিং ডেটার শারীরিক অনুলিপিকরতে প্রয়োজন ( N )।

উদাহরণস্বরূপ, সদস্য ফাংশনগুলির জন্য

auto operator[](size_type pos) const -> const_reference;
auto operator[](size_type pos) -> reference;

… যা একটি COW বাস্তবায়নে - স্ট্রিংয়ের মানটি ভাগ করে নেওয়ার জন্য স্ট্রিং ডেটা অনুলিপি করতে পারে, সি ++ 11 স্ট্যান্ডার্ডের প্রয়োজন

সি ++ 11 §21.4.5 / 4 :

জটিলতা: ধ্রুবক সময়।

… যা এই জাতীয় ডেটা অনুলিপি করার বিষয়টি বাতিল করে এবং তাই, COW।

সি ++ 03 দ্বারা সমর্থিত কাউ বাস্তবায়নের না এই ধ্রুবক জটিলতা প্রয়োজনীয়তা না থাকার, এবং, নির্দিষ্ট নিয়ন্ত্রণমূলক অবস্থার অধীনে, এর কল, যার ফলে operator[](), at(), begin(), rbegin(), end(), অথবা rend()বাতিল উল্লেখ পয়েন্টার এবং iterators STRING টি আইটেম উল্লেখ অর্থাৎ সম্ভবত বহন করতে একটি COW ডেটা অনুলিপি করা হচ্ছে। এই সমর্থনটি সি ++ 11 এ সরানো হয়েছে।


সি + ডাব্লু কি সি ++ 11 অবৈধ নিয়মের মাধ্যমেও নিষিদ্ধ?

আর একটি উত্তরে যা লেখার সময় সমাধান হিসাবে নির্বাচিত হয়, এবং যা ভারীভাবে উপবিষ্টিত হয় এবং তাই আপাতভাবে বিশ্বাস করা হয়, এটি দৃ that়ভাবে জানায় যে

" একটি COW স্ট্রিংয়ের জন্য, অ-কল করার জন্য const operator[]একটি অনুলিপি তৈরি করতে হবে (এবং রেফারেন্সকে অবৈধ করা), যা উপরের [উদ্ধৃত] অনুচ্ছেদে [সি ++ 11 §21.4.1 / 6] দ্বারা অনুমোদিত নয়। সুতরাং, সি ++ 11 এ কোনও COW স্ট্রিং থাকা বৈধ নয়।

এই দাবী দুটি প্রধান উপায়ে ভুল এবং বিভ্রান্তিকর:

  • এটি ভুলভাবে নির্দেশ করে যে কেবল অ- constআইটেম অ্যাকসেসরগুলিতে একটি COW ডেটা অনুলিপি করা দরকার।
    তবে constআইটেম অ্যাক্সেসকারীদেরও ডেটা অনুলিপি তৈরি করতে হবে, কারণ তারা ক্লায়েন্ট কোডকে রেফারেন্স বা পয়েন্টার গঠনের অনুমতি দেয় যে (সি ++ 11 এ) পরে সেই অপারেশনগুলির মাধ্যমে পরে অকার্যকর হওয়ার অনুমতি নেই যা COW ডেটা অনুলিপি তৈরি করতে পারে।
  • এটি ভুলভাবে ধরে নিয়েছে যে COW ডেটা অনুলিপি করার কারণে রেফারেন্স অবৈধ হতে পারে।
    তবে একটি সঠিক বাস্তবায়নে COW ডেটা অনুলিপি করা, স্ট্রিংয়ের মানটি ভাগ করে নেওয়া, এমন কোনও রেফারেন্স যা অবৈধ হতে পারে তার আগে একটি পর্যায়ে সম্পন্ন করা হয়।

কীভাবে একটি সঠিক সি ++ 11 COW বাস্তবায়ন basic_stringকাজ করবে তা দেখার জন্য, যখন এই (O) 1 টি প্রয়োজনীয়তাগুলি এটি অবৈধ করে তোলে, তখন এমন একটি বাস্তবায়নের কথা চিন্তা করুন যেখানে স্ট্রিং মালিকানা নীতিগুলির মধ্যে পরিবর্তন করতে পারে। একটি স্ট্রিং উদাহরণ পলিসি শেয়ারে শুরু হয়। এই নীতি সক্রিয় সঙ্গে কোনও বাহ্যিক আইটেম রেফারেন্স থাকতে পারে। উদাহরণটি অনন্য নীতিতে রূপান্তর করতে পারে এবং কোনও আইটেম রেফারেন্স সম্ভাব্যরূপে কল হিসাবে যেমন তৈরি হয় .c_str()(অন্তত যদি এটি অভ্যন্তরীণ বাফারটিতে একটি পয়েন্টার তৈরি করে) তখন এটি অবশ্যই করতে হবে । একাধিক উদাহরণের মানটির মালিকানা ভাগ করে নেওয়ার ক্ষেত্রে এটি স্ট্রিং ডেটা অনুলিপি করে। অনন্য নীতিতে স্থানান্তরিত হওয়ার পরে উদাহরণটি কেবলমাত্র এমন কোনও ক্রিয়াকলাপের মাধ্যমে শেরে ফিরে যেতে পারে যা অ্যাসাইনমেন্টের মতো সমস্ত রেফারেন্সকে অকার্যকর করে দেয়।

সুতরাং, যখন উত্তরটির উপসংহারটি, COW স্ট্রিংগুলিকে বাতিল করা হয়েছে, সঠিক, প্রস্তাবিত যুক্তিটি ভুল এবং দৃ strongly়ভাবে বিভ্রান্তিকর।

আমি সন্দেহ করি যে এই ভুল বোঝাবুঝির কারণটি সি ++ 11 এর এনেক্সেক্স সি-তে একটি নন-আদর্শিক নোট:

সি ++ 11 §C.2.11 [বিভক্ত।

পরিবর্তন : basic_stringপ্রয়োজনীয়তা আর রেফারেন্স গণনা করা স্ট্রিং অনুমতি দেয় না যুক্তি
: রেফারেন্স গণনা করা স্ট্রিং সঙ্গে অবৈধতা সূক্ষ্মভাবে পৃথক। এই পরিবর্তনটি এই আন্তর্জাতিক মানের জন্য আচরণ (sic) নিয়মিত করে।
মূল বৈশিষ্ট্যের উপর প্রভাব: বৈধ সি ++ 2003 কোডটি এই আন্তর্জাতিক স্ট্যান্ডার্ডে ভিন্নভাবে কার্যকর করতে পারে

এখানে যুক্তিটি প্রাথমিকভাবে ব্যাখ্যা করে যে কেন কেউ সি ++ 03 বিশেষ COW সমর্থন অপসারণের সিদ্ধান্ত নিয়েছে। এই যুক্তি, কেন , মানটি কীভাবে কার্যকরভাবে COW বাস্তবায়নকে অস্বীকার করে না। স্ট্যান্ডার্ডটি O (1) প্রয়োজনীয়তার মাধ্যমে COW অস্বীকার করে।

সংক্ষেপে, সি ++ 11 অবৈধকরণের নিয়মগুলি কোনও COW বাস্তবায়নকে অস্বীকার করে না std::basic_string। তবে তারা কমপক্ষে জি ++ এর স্ট্যান্ডার্ড লাইব্রেরি বাস্তবায়নের মতো একটি যুক্তিসঙ্গতভাবে দক্ষ সীমাহীন সি ++ 03-স্টাইলের COW বাস্তবায়নকে বাতিল করে দেয়। বিশেষ C ++ 03 COW সমর্থন ব্যবহারিক দক্ষতার অনুমতি দিয়েছে, বিশেষত constআইটেম অ্যাকসেসরগুলি ব্যবহার করে, অবৈধকরণের জন্য সূক্ষ্ম, জটিল নিয়মের ব্যয়:

সি ++ 03 §21.3 / 5 এর মধ্যে "প্রথম কল" COW সমর্থন অন্তর্ভুক্ত:

"basic_string অনুক্রমের উপাদানগুলির সাথে উল্লেখ করে রেফারেন্স, পয়েন্টার এবং পুনরাবৃত্তকারীগুলি সেই basic_stringবস্তুর নিম্নলিখিত ব্যবহারগুলি দ্বারা অবৈধ হতে পারে :
- swap()সদস্যবিহীন ফাংশনগুলির (21.3.7.8), operator>>()(21.3.7.9) এবং getline()(21.3 ) হিসাবে একটি যুক্তি হিসাবে । 7.9)।
- একটি তর্ক হিসাবে basic_string::swap()
- কলিং data()এবং c_str()সদস্য ফাংশন।
- অ কলিং constসদস্য ফাংশন, ব্যতীত operator[](), at(), begin(), rbegin(), end(), এবং rend()
- ফরম ছাড়া উপরে ব্যবহার সম্পর্কে কোন পরবর্তী insert()এবং erase()যা আসতে iterators, অ- প্রথম কল constসদস্য ফাংশন operator[](), at(), begin(), rbegin(),end(), বা rend()

এই নিয়মগুলি এত জটিল এবং সূক্ষ্ম যে আমি অনেক প্রোগ্রামারকে সন্দেহ করি, যদি কোনও হয় তবে একটি যথার্থ সংক্ষিপ্তসার দিতে পারে। আমি পারিনি.


যদি ও (1) প্রয়োজনীয়তা অবজ্ঞা করা হয় তবে কী হবে?

যদি উদাহরণস্বরূপ সি ++ 11 ধ্রুবক সময়ের প্রয়োজনীয়তাগুলি operator[]উপেক্ষা করা হয়, তবে এর জন্য COW basic_stringপ্রযুক্তিগতভাবে সম্ভব, তবে কার্যকর করা কঠিন।

অপারেশনগুলি যা COW ডেটা অনুলিপি ব্যতীত কোনও স্ট্রিংয়ের বিষয়বস্তু অ্যাক্সেস করতে পারে তার মধ্যে রয়েছে:

  • মাধ্যমে কনকনাটেশন +
  • মাধ্যমে আউটপুট <<
  • basic_stringস্ট্যান্ডার্ড লাইব্রেরি ফাংশনগুলির পক্ষে যুক্তি হিসাবে ব্যবহার করা ।

আধুনিক কারণ গ্রন্থাগারটি নির্দিষ্ট জ্ঞান এবং নির্মাণের উপর নির্ভর করার অনুমতিপ্রাপ্ত ly

অতিরিক্তভাবে একটি বাস্তবায়ন COW ডেটা অনুলিপকে ট্রিগার না করে স্ট্রিং সামগ্রীগুলিতে অ্যাক্সেসের জন্য বিভিন্ন অ-মানক ফাংশন সরবরাহ করতে পারে।

একটি প্রধান জটিল কারণটি হ'ল সি ++ এ basic_stringআইটেমের অ্যাক্সেস অবশ্যই ডেটা অনুলিপি করতে হবে (স্ট্রিং ডেটা ভাগ করে নেবে না) তবে নিক্ষেপ করতে হবে না , যেমন সি ++ 11 §21.4.5 / 3 " নিক্ষেপ : কিছুই নয়"। এবং তাই এটি COW ডেটা অনুলিপি করার জন্য একটি নতুন বাফার তৈরি করতে সাধারণ গতিশীল বরাদ্দ ব্যবহার করতে পারে না। এই সমস্যা এড়ানোর ওয়ান ওয়ে একটি বিশেষ গাদা যেখানে মেমরি যাবে ব্যবহার করা সংরক্ষিত আসলে বরাদ্দ হচ্ছে না, এবং তারপর স্ট্রিং মান প্রতিটি যৌক্তিক রেফারেন্সের জন্য প্রয়োজনীয় পরিমাণ রাখি। এ জাতীয় স্তূপে সংরক্ষণ এবং সংরক্ষণের ব্যবস্থা অবিচ্ছিন্ন সময় হতে পারে, হে (1), এবং যে পরিমাণ ইতিমধ্যে সংরক্ষণ করা হয়েছে তা বরাদ্দ করা যেতে পারেnoexcept। স্ট্যান্ডার্ডের প্রয়োজনীয়তাগুলি মেনে চলার জন্য, এই পদ্ধতির সাথে দেখে মনে হয় স্বতন্ত্র বরাদ্দকারীদের জন্য এই জাতীয় বিশেষ সংরক্ষণের ভিত্তিতে একটি গাদা থাকা দরকার।


দ্রষ্টব্য:
¹ constআইটেমটি ট্রিগার অ্যাকসেসর অনুলিপি একটি গাভী ডেটা কারণ এটি ক্লায়েন্ট কোড ডেটা, যার ফলে এটি পরবর্তী তথ্য দ্বারা বাতিল করার অনুমতি না যেমন অ দ্বারা আলোড়ন সৃষ্টি অনুলিপি করা একটি রেফারেন্স বা পয়েন্টার প্রাপ্ত করা সম্ভব constআইটেমটি অ্যাকসেসর।


3
" আপনার উদাহরণটি ভুল-সি -+ 11 প্রয়োগের একটি ভাল উদাহরণ P সম্ভবত এটি সি ++ 03 এর জন্য সঠিক ছিল" " হ্যাঁ এটি উদাহরণের পয়েন্ট । এটি CW+ স্ট্রিংয়ে বৈধ ছিল এমন একটি COW স্ট্রিং দেখায় কারণ এটি পুরানো পুনরাবৃত্তকারী অবৈধকরণের নিয়মগুলিকে ভঙ্গ করে না এবং সি ++ 11-এ বৈধ নয় কারণ এটি নতুন পুনরাবৃত্তির অবৈধকরণ বিধিকে ভঙ্গ করে। এবং এটি উপরের মন্তব্যে আমি উদ্ধৃত বিবৃতিটির সাথেও স্ববিরোধী।
জোনাথন ওয়েকেলি

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

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

2
তাই যখন আপনি টেকনিক্যালি সঠিক যে জটিলতা গ্যারান্টী কি লেখা থেকে আটকায় হয় কোন ফর্ম গরুর, আসলেই হল [basic.string] / 5 যে আপনি কোনো সত্যি সত্যি লেখা থেকে আটকায় দরকারী কাউ স্ট্রিং এর ফর্ম।
নিকল বোলাস

4
@ জোনাথন ওয়াচলি: (১) আপনার উক্তিটি প্রশ্ন নয়। এখানে প্রশ্নটি রয়েছে: “আমি কি ঠিক করছি যে সি ++ 11 স্টাড :: স্ট্রিংয়ের COW ভিত্তিক বাস্তবায়ন স্বীকার করে না? যদি তা হয় তবে এই সীমাবদ্ধতাটি নতুন মান (কোথায়) কোথাও স্পষ্টভাবে বলা হয়েছে? " (২) আপনার মতামত যে কোনও COW std::string, ও (1) প্রয়োজনীয়তা উপেক্ষা করার সময় অকার্যকর হবে, আপনার মতামত। পারফরম্যান্স কী হতে পারে তা আমি জানি না, তবে আমি মনে করি যে এই উত্তরের সাথে কোনও প্রাসঙ্গিকতার চেয়ে এই অনুভূতিটি, এটি যে ভাইবগুলি সরবরাহ করে, তার পক্ষে এই দৃser়তা আরও এগিয়ে দেওয়া হয়েছে।
চিয়ার্স এবং এইচটিএইচ - Alf

0

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

একটি সহজ তুলনা পরীক্ষার জন্য আমার আজ এটি চেষ্টা করার সময় হয়েছিল: ম্যাপের সমস্ত মানচিত্রের স্ট্রিং / গরুযুক্ত প্রতিটি নোডের সাথে স্ট্রিং / গাভী দ্বারা মাপ করা ম্যাপের মানচিত্র (আমাদের কাছে এনএক্সএন সংখ্যা রয়েছে)।

স্ট্রিংগুলির সাথে আকার ~ 300 বাইট এবং এন = 2000 গরু সামান্য দ্রুত এবং প্রায় ক্রম কম মেমরির ক্রম ব্যবহার করে। নীচে দেখুন, মাপগুলি কেবিএসে রয়েছে, রান বি রয়েছে গরুর সাথে।

~/icow$ ./tst 2000
preparation a
run
done a: time-delta=6 mem-delta=1563276
preparation b
run
done a: time-delta=3 mem-delta=186384
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.