لزوماً هنگام انجام مبادله () شامل نمی شود - چگونه می تواند این مسئله به یک مشکل تبدیل شود؟

ساخت وبلاگ

همانطور که در مقاله CPPreference فوق الذکر شرح داده شده است ، و پرونده ای که برای استفاده از این الگوریتم باید #include کنم #include نیستبشراگر من به عملکرد ارائه شده توسطدر مبادله من () ، چگونه این می تواند منجر به یک مشکل شود؟من باید #خودم در پرونده ای که تعویض من را تعریف می کند (). سناریو باید شبیه به موارد زیر باشد: من پرونده ای دارم که #کلاس خود را با مبادله () ارائه شده توسط کاربر () و عنوان الگوریتمی که استفاده می کنم ، #شامل می شود. در نتیجه ، هرگز نباید در مورد اینکه آیا الگوریتم #line انجام می دهد ، مشکلی ایجاد شودیا نه. من ممکن است سوء تفاهم هایی در مورد چگونگی تعامل #include و تلفیقی با یکدیگر در برخی از سناریوهای مختلف وجود داشته باشد. کدام وضعیت به طور بالقوه می تواند در اینجا به مسائل تدوین منجر شود؟

دنبال کردن 5 اکتبر 2021 در ساعت 11:40 پرسید ruperrrt ruperrrt 459 2 2 نشان نقره 12 12 نشان برنز

با نگاهی به اجرای GCC ، به نظر می رسد که شامل "UK-300" است. به امید اینکه کسی معنی آن را روشن کند.

5 اکتبر 2021 در 12:25

به عنوان مثال Tharsalys ، در libstdc ++ ، std :: الگوریتم پارتیشن از std :: iter_swap داخلی استفاده می کند ، که در اینجا در بیت/stl_algobase. h تعریف شده است. این هدر شامل هیچ عنوان دیگری نیست که هدر درگیر آن باشد تا آنجا که می توانم بگویم. من فقط شامل // برای std :: مبادله ، این خط را ببینید. به نظر می رسد موردی است که توسط الگوریتمی که از مبادله استفاده می کند ، گنجانده نشده است.

5 اکتبر 2021 در 12:58

daniellangr فکر می کنم می توانیم نتیجه بگیریم که این کار به "مستقیم" شامل می شودیا نه. بنابراین آیا موردی وجود دارد که در سناریوی شرح داده شده در سوال قرار بگیریم؟

6 اکتبر 2021 در 7:08

DanielTharsalys مطابق با cppreference همچنین std :: مبادله را تعریف می کند. بنابراین یادداشت ممکن است در مورد عملکردی باشد که به طور خاص توسط آن ارائه شده است؟

6 اکتبر 2021 در 7:52

ruperrrt std :: مبادله از آنجا منتقل شدبه C ++ 11. Cppreference دارای "تا C ++ 11" و "از C ++ 11" است که به راحتی از دست می رود

13 اکتبر 2021 در 9:42

2 پاسخ 2

مرتب شده توسط: تنظیم مجدد به طور پیش فرض

بیایید سعی کنیم یادداشتی را که از cppreference نقل کرده اید درک کنیم.

مشخص نیست که آیا در واقع وقتی توابع استاندارد کتابخانه مبادله را انجام می دهند ، در واقع گنجانده شده است ، بنابراین مبادله () ارائه شده توسط کاربر نباید انتظار داشته باشد که شامل آن شود.

به عنوان مثال ، std :: مرتب سازی ممکن است مبادله را انجام دهد. برای استفاده از std :: مرتب سازی ، شما باید درج کنید. این بیانیه اساساً می گوید ، با وجود این ، ممکن است شامل نشد. این نتیجه می گیرد که کد زیر ممکن است مشکل ساز باشد.

#include int main (); std::sort(arr, arr + 3); std::swap(arr[0], arr[1]); // may error out here> 

این غیر شهودی است، زیرا std::sort خود std::swap را به صورت داخلی انجام می دهد. برای حفظ امنیت، در صورت نیاز به std::swap همیشه صریحاً اضافه کنید. فرض نکنید که برخی از هدرهای استاندارد کتابخانه دیگر که از std::swap استفاده می کنند، برای شما گنجانده شده اند. کد زیر همیشه باید کار کند، در حالی که #include در نگاه اول غیر ضروری به نظر می رسد.

#include #include int main(); std::sort(arr, arr + 3); std::swap(arr[0], arr[1]);> 

دنبال کردن پاسخ داده شده در 13 اکتبر 2021 در 8:54 لینگشی لینگشی 14. 4k 1 1 نشان طلا 37 37 نشان نقره 93 93 نشان برنز

نقطه در. اگرچه استفاده از std::swap تقریباً مطمئناً در آن نقطه ایمن خواهد بود، حتی اگر در آن گنجانده نشود، زیرا std::sort برای استفاده از آن نیاز به تعریف آن دارد. یک مورد شکست واقعی تر، استفاده از هر تابع دیگری است که در تعریف شده است، به عنوان مثال. std::exchange .

13 اکتبر 2021 ساعت 8:59

@KonradRudolph یک پیاده سازی برای تعریف swap در فضای نام دیگری غیر از std آزاد است، تا زمانی کهبا استفاده از s it در std . این برای اطمینان از اینکه در مجموعه اضافه بار است که مرتب سازی استفاده می کند، جدا است

13 اکتبر 2021 ساعت 9:37

پاسخ کوتاه این خواهد بود که بدون #include صریح، هیچ تضمینی برای std::swap بازگشتی وجود ندارد در صورتی که تعویض سفارشی برای Foo s وجود نداشته باشد. منجر به خطاهای کامپایل می شود.

اگر از std استفاده می شود::swap; عبارت در جایی در کد - مال شما یا داخل الگوریتم - سپس تابع std::swap باید قبلاً گنجانده شده باشد، در غیر این صورت با یک خطای کامپایل مواجه می شوید.

چیزی که cppreference در آن وجود دارد این است که هیچ تضمینی وجود ندارد که std::foo_algorithm شامل و استفاده از std::swap; قبل از فراخوانی swap(a, b) ساخت. توجه داشته باشید که آن طور که باید از نام غیر واجد شرایط برای مبادله استفاده می کند.

این بدان معناست که اگر کلاس شما به وجود std::swap بستگی دارد، زیرا فاقد هر گونه تابع تعویض سفارشی است، فراخوانی std::foo_algorithm ممکن است منجر به خطاهای کامپایل شود که می گویند تابع swap(Foo&, Foo&) مناسب به دلیل std وجود ندارد.:: تعویض به طور خودکار گنجانده نشده است. راه حل آسان این است که #include را قبل از #include قرار دهید.

اما، اگر یک مبادله سفارشی داشته باشید و الگوریتم بتواند آن را پیدا کند (یا به این دلیل که مستقیماً در فضای نام فعلی گنجانده شده است یا ADL وارد می شود)، همه چیز به خوبی کامپایل می شود. غیر مرتبط با آن، swap شما باید از std استفاده کند::swap; مبادله (a, b); به هر حال ساخت، بنابراین std::swap به احتمال زیاد همیشه وجود دارد اگر swap شما باشد.

سیگنال های تجاری...
ما را در سایت سیگنال های تجاری دنبال می کنید

برچسب : نویسنده : عبدالله بوتیمار بازدید : <-PostHit-> تاريخ : پنجشنبه 16 شهريور 1402 ساعت: 0:34