কেন std :: অদলবদল C ++ 20 এর পূর্বে কনটেক্সপ্রপ চিহ্নিত করা হয়নি?


14

সি ++ ২০ এ, std::swapএকটি constexprফাংশন হয়ে যায় ।

আমি জানি যে স্ট্যান্ডার্ড লাইব্রেরি জিনিসগুলি চিহ্নিত করার ক্ষেত্রে ভাষার চেয়ে পিছিয়ে ছিল constexpr, তবে <algorithm>২০১ 2017 সালের মধ্যে অন্যান্য বিষয়গুলির মতো অনেকটা কনসেক্সট্রপ ছিল। তবুও - std::swapছিল না। আমি অস্পষ্টভাবে মনে করি কিছু অদ্ভুত ভাষার ত্রুটি রয়েছে যা সেই চিহ্নটিকে আটকাচ্ছে তবে আমি বিবরণগুলি ভুলে গেছি।

কেউ এই সংক্ষিপ্ত এবং পরিষ্কারভাবে ব্যাখ্যা করতে পারেন?

অনুপ্রেরণা: C ++ 11 / C ++ 14 কোডে একটি পছন্দ- std::swap()মতো ফাংশন চিহ্নিত করার জন্য কেন এটি খারাপ ধারণা হতে পারে তা বোঝার দরকার constexpr

উত্তর:


11

অদ্ভুত ভাষা ইস্যুটি সিডাব্লুজি 1581 :

ধারা 15 [বিশেষ] পুরোপুরি স্পষ্ট যে বিশেষ সদস্য ফাংশনগুলি কেবল গন্ধযুক্ত-ব্যবহৃত হলে কেবল সুস্পষ্টভাবে সংজ্ঞায়িত হয়। এটি অমূল্য প্রসঙ্গে নিয়মিত প্রকাশের জন্য একটি সমস্যা তৈরি করে:

struct duration {
  constexpr duration() {}
  constexpr operator int() const { return 0; }
};

// duration d = duration(); // #1
int n = sizeof(short{duration(duration())});

এখানে সমস্যাটি হ'ল আমাদের constexpr duration::duration(duration&&)এই প্রোগ্রামটিতে স্পষ্টভাবে সংজ্ঞায়িত করার অনুমতি নেই , সুতরাং প্রারম্ভিকের তালিকায় প্রকাশটি একটি ধ্রুবক প্রকাশ নয় (কারণ এটি একটি কনসেক্সট্রিপ ফাংশনকে ডাকে যা সংজ্ঞায়িত হয়নি), তাই বন্ধনীযুক্ত আরম্ভকারীটি সংকীর্ণ রূপান্তর ধারণ করে সুতরাং, প্রোগ্রামটি দুর্গঠিত।

যদি আমরা লাইন # 1টিকে আপত্তিহীন করি, তবে মুভ কনস্ট্রাক্টর সুস্পষ্টভাবে সংজ্ঞায়িত করা হয়েছে এবং প্রোগ্রামটি বৈধ। দূরত্বে এই ভুতুড়ে কাজটি অত্যন্ত দুর্ভাগ্যজনক। বাস্তবায়নগুলি এই পয়েন্টে ডাইভারেজ করে।

আপনি ইস্যুটির বাকী বিবরণ পড়তে পারেন।

এই ইস্যুটির জন্য একটি প্রস্তাব 2017 সালে আলবুকার্কে P0859 এ গৃহীত হয়েছিল (সি ++ 17 প্রেরণের পরে)। উভয়ই C ++ 20 এর জন্য ( P0879 এconstexpr std::swap সমাধান করা ) এবং একটি ( P1065-এ সমাধান করা , যার CWG1581 উদাহরণ রয়েছে) উভয়ই রাখতে সক্ষম হওয়ায় এই সমস্যাটি ব্লককারী ছিল ।constexpr std::invoke


এখানে সবচেয়ে সহজ উদাহরণটি বোঝার জন্য, আমার মতে, এল 10 ভিএম বাগ রিপোর্টের কোডটি পি 1065-তে নির্দেশিত:

template<typename T>
int f(T x)
{
    return x.get();
}

template<typename T>
constexpr int g(T x)
{
    return x.get();
}

int main() {

  // O.K. The body of `f' is not required.
  decltype(f(0)) a;

  // Seems to instantiate the body of `g'
  // and results in an error.
  decltype(g(0)) b;

  return 0;
}

CWG1581 সম্পর্কে সব হয় যখন constexpr সদস্য ফাংশন সংজ্ঞায়িত করা হয়, এবং রেজল্যুশন নিশ্চিত করে যে তারা শুধুমাত্র যখন ব্যবহৃত সংজ্ঞায়িত করছি। P0859 পর উপরে সুগঠিত হয় (ধরণ bহয় int)।

যেহেতু std::swapএবং std::invokeউভয়কেই সদস্য ফাংশনগুলির জন্য পরীক্ষা করা (পূর্বে নির্মাণ কল / কার্যক্রমে এবং পরবর্তী কলের অপারেটর / সারোগেট কলগুলি) পরবর্তী সময়ে এই সমস্যার সমাধানের উপর নির্ভর করে।


সুতরাং, কেন CWG-1581 স্ব্যাপ ফাংশনটিকে কনস্টেক্সপ্র হিসাবে চিহ্নিত করতে বা অনাকাঙ্ক্ষিত করে?
einpoklum

3
@einpoklum swap 'র প্রয়োজন std::is_move_constructible_v<T> && std::is_move_assignable_v<T>হয় true। বিশেষ সদস্য ফাংশনগুলি এখনও তৈরি না করা হলে এটি ঘটতে পারে না।
নাথান অলিভার

@ নাথান অলিভার: এটি আমার উত্তরে যুক্ত হয়েছে।
einpoklum

5

কারন

(@ নাথান অলিভারের কারণে)

একটি constexprঅদলবদল ফাংশন অনুমোদনের জন্য , আপনাকে এই ফাংশনটির জন্য টেমপ্লেট ইনস্ট্যান্ট করার আগে - পরীক্ষা করতে হবে - অদলবদল প্রকারটি মুভ-কনস্ট্রাকটেবল এবং মুভ-এসেসেবলযোগ্য। দুর্ভাগ্যক্রমে, কেবলমাত্র সি ++ 20 তে ভাষা সমাধানের কারণে, আপনি এটি পরীক্ষা করতে পারবেন না , যেহেতু সংকলকটি যতটা প্রাসঙ্গিকভাবে সম্পর্কিত ততক্ষণ সম্পর্কিত সদস্য কার্যগুলি এখনও সংজ্ঞায়িত করা হয়নি।

কালানুক্রম

  • 2016: অ্যান্টনি পোলুকিন P0202 কে প্রস্তাব জমা দেয় , সমস্ত <algorithm>কার্য হিসাবে চিহ্নিত করে constexpr
  • স্ট্যান্ডার্ড কমিটির মূল কার্যকারী গ্রুপটি ত্রুটিযুক্ত সিডাব্লুজি -1581 নিয়ে আলোচনা করেছে । এই সমস্যাটি এটিকে সমস্যাযুক্ত করেছে constexpr std::swap()এবং এটিও constexpr std::invoke()- উপরে ব্যাখ্যা দেখুন।
  • 2017: অ্যান্টনি বাদ দেওয়ার জন্য এবং কিছু অন্যান্য নির্মাণগুলি কয়েকবার তার প্রস্তাবটি সংশোধন করেstd::swap এবং এটি সি ++ 17 এ গৃহীত হয়।
  • 2017: সিডাব্লুজি -1581 ইস্যুটির একটি রেজোলিউশন P0859 হিসাবে জমা দেওয়া হয়েছে এবং 2017 সালে মানক কমিটি দ্বারা গৃহীত হয়েছে (তবে সি ++ 17 প্রেরণের পরে)।
  • 2017 এর শেষ: অ্যান্টনি সিডাব্লুজিstd::swap() -1581 এর রেজোলিউশনের পরে কনটেক্সপ্রপ তৈরি করার জন্য একটি পরিপূরক প্রস্তাব, P0879 জমা দিয়েছে
  • 2018: পরিপূরক প্রস্তাবটি (?) সি ++ 20 এ গৃহীত হয়েছে। ব্যারি যেমন উল্লেখ করেছেন, std::invoke()ঠিক তেমন কনসেক্সপ্রস ফিক্সও ।

আপনার নির্দিষ্ট কেস

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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.