ক্লাব / উইন এর অধীনে <bool> উপাদানগুলিতে কেন স্টাডি :: অদলবদল করে না?


14

আমার এই কোড আছে:

#include <vector>
#include <utility>

int main()
{
   std::vector<bool> vb{true, false};
   std::swap(vb[0], vb[1]);
}

পক্ষপাতহীনতা সম্পর্কে তর্ক, vector<bool>এটি ঠিক কাজ করছিল:

  • ম্যাকের জন্য ঝাঁকুনি
  • উইন্ডোজ জন্য ভিজ্যুয়াল স্টুডিও
  • লিনাক্সের জন্য জিসিসি

তারপরে আমি এটিকে উইন্ডোজে কলং দিয়ে তৈরি করার চেষ্টা করেছি এবং নিম্নলিখিত ত্রুটিটি পেয়েছি (সংক্ষিপ্ত):

error: no matching function for call to 'swap'
                                std::swap(vb[0], vb[1]);
                                ^~~~~~~~~

note: candidate function [with _Ty = std::_Vb_reference<std::_Wrap_alloc<std::allocator<unsigned int> > >, $1 = void] not viable: expects an l-value for 1st argument
inline void swap(_Ty& _Left, _Ty& _Right) _NOEXCEPT_COND(is_nothrow_move_constructible_v<_Ty>&&

আমি অবাক হয়েছি যে প্রয়োগগুলি জুড়ে ফলাফল পৃথক।

এটি উইন্ডোজে কলঙ্কের সাথে কেন কাজ করে না?


সুতরাং আমি অনুমান করি যে স্পষ্টতা প্রয়োজন তা হ'ল: operator[]কোনও মূল্যমানের ফলাফল কি ? এবং std::swapমূল্য এবং xvalue কাজ করতে পারেন ?
ম্যাজেজ

@ মেগেজ হ্যাঁ না। এই প্রশ্নটি অন্য দিন ব্যক্তিগতভাবে "বাস্তবের জন্য" জিজ্ঞাসা করা হয়েছিল, এবং আমি ভেবেছিলাম এটি যথেষ্ট মজাদার ছিল যে উত্তরটি ছিল "ঝাঁকুনি / উইন ভাঙ্গা হয়নি; কোডটি পুরো সময়টি নষ্ট হয়েছিল তবে মূলধারার সরঞ্জামচেন কম্বো আপনাকে কখনই বলার বিরক্ত করেনি? "এটি এখানে লিখতে: পি
অরবিটে

2
ঠিক একটি এফওয়াইআই হিসাবে, এটি ভিএস 2019-এ /permissive-(কনফারেন্স) দিয়ে সংকলন করে না , যা সাধারণত যেভাবেই ব্যবহার করা উচিত;)
ক্রিসএমএম

1
পছন্দ করেছেন কনফরমেশন মোড অফ ধাঁধার একটি অংশ ছিল। (যদিও এটি
সন্ধানের

উত্তর:


15

কোনও সরঞ্জামচেইনে সংকলনের জন্য মানটির প্রয়োজন হয় না !

প্রথমটি স্মরণ করুন যা vector<bool>অদ্ভুত এবং এটিকে সাবস্ক্রিপশন করা আপনাকে প্রকৃতের std::vector<bool>::referenceপরিবর্তে প্রক্সি প্রকারের একটি অস্থায়ী অবজেক্ট দেয় bool&

ত্রুটি বার্তাটি আপনাকে বলছে যে এটি constজেনেরিক template <typename T> std::swap(T& lhs, T& rhs)প্রয়োগের ক্ষেত্রে অস্থায়ী রেফারেন্সটিতে এই অস্থায়ীটিকে আবদ্ধ করতে পারে না ।

এক্সটেনশানগুলি!

যাইহোক, দেখা যাচ্ছে যে libstdc ++ এর জন্য একটি ওভারলোডকে সংজ্ঞায়িত করেstd::swap(std::vector<bool>::reference, std::vector<bool>::reference) তবে এটি স্ট্যান্ডার্ডের একটি এক্সটেনশন (বা এটি যদি সেখানে থাকে তবে আমি এর পক্ষে কোনও প্রমাণ পাই না)।

libc ++ এটিও করে

আমি অনুমান করেছি যে ভিজ্যুয়াল স্টুডিও স্টাডলিব বাস্তবায়ন, যা আপনি এখনও ব্যবহার করছেন, তা নয় , তবে আঘাতের অপমানের জন্য আপনি ভিএস- তে রেফারেন্সগুলি মূল্যায়নের জন্য অস্থায়ী সংস্থাগুলি আবদ্ধ করতে পারেন (যদি না আপনি কনফারেন্স মোড ব্যবহার করছেন), স্ট্যান্ডার্ড, "জেনেরিক", std::swapফাংশন কার্যকর হয় যতক্ষণ না আপনি কঠোর কলং সংকলকটির জন্য ভিএস সংকলককে বিকল্প হিসাবে স্থান দেন।

ফলস্বরূপ, আপনি যে তিনটি সরঞ্জামচেনের জন্য এটি আপনার জন্য কাজ করেছে সেগুলির সমস্তটির উপরেই আপনি এক্সটেনশনের উপর নির্ভর করছেন এবং উইন্ডোজ সংমিশ্রণে কলঙ্কটি কেবলমাত্র কঠোর সম্মতি প্রদর্শনকারী।

(আমার মতে, এই তিনটি সরঞ্জামচেনগুলি এটি নির্ণয় করা উচিত ছিল যাতে আপনি পুরো সময় অ-বহনযোগ্য কোডটি প্রেরণ না করে 😊)

এখন কি?

এটা আপনার নিজের বিশেষজ্ঞতা যোগ করার জন্য প্রলুব্ধ হতে পারে std::swapএবং std::vector<bool>::reference, কিন্তু আপনি মান ধরনের জন্য এই কাজ করতে মঞ্জুরিপ্রাপ্ত নন; প্রকৃতপক্ষে, এটি ওভারলোডগুলির সাথে দ্বন্দ্ব করবে যেগুলি libstdc ++ এবং libc ++ এক্সটেনশন হিসাবে যুক্ত করতে বেছে নিয়েছে।

সুতরাং, বহনযোগ্য এবং অনুগত হতে আপনার কোড পরিবর্তন করা উচিত

সম্ভবত একটি ভাল পুরানো:

const bool temp = vb[0];
vb[0] = vb[1];
vb[1] = temp;

বা বিশেষ স্থিতিশীল সদস্য ফাংশনটি ব্যবহার করুন যা আপনি যা চান ঠিক তেমন করে :

std::vector<bool>::swap(vb[0], vb[1]);

নিম্নরূপ স্পেলেযোগ্য:

vb.swap(vb[0], vb[1]);

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

@ নাথান অলিভার -ইনস্টেটমোনিকা ভাল, ঠিক আছে। তাদের কি কমপক্ষে এ জাতীয় জিনিসগুলির ব্যবহার নির্ণয় করতে হবে না? eel.is/c++draft/intro.comp Equipment#8
রেস

@ লাইটনেসেসেস উইথমোনিকার এমন কোনও ভাষা আছে যা এই সম্প্রসারণকে নিষেধ করে?
মার্জেজ

@ ম্যাগজেজ দুঃখিত, আমি সমস্ত বিদ্যমান ভাষায় রূপান্তরকারী নই তাই এর জবাব আমি দিতে পারব না
আলোকিত ঘোড়দৌড়ের কক্ষপথ

আমি নিশ্চিত নই যে এই ডকুমেন্ট অনুসারে এই জাতীয় এক্সটেনশানগুলি খারাপ ব্যবহার করেছে যা প্রযোজ্য। তারা একটি ওভারলোড যুক্ত করেছে std::vector<bool>::referenceযাতে কোনও কিছুই আসলে খারাপভাবে তৈরি হয় না। আমার কাছে মনে হচ্ছে এমন কিছু ব্যবহার করার জন্য char * foo = "bar";ডায়াগনস্টিকের প্রয়োজন হবে যেহেতু এটি দুর্বল।
নাথান অলিভার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.