কনস্টেক্সপ্র - যদি ফেলে দেওয়া বিবৃতি পুরোপুরি পরীক্ষা করা হয় কেন?


14

আমি জিসিসি 10 তে সি ++ 20 কনস্টিভাল নিয়ে ঘোরাঘুরি করছি এবং এই কোডটি লিখেছি

#include <optional>
#include <tuple>
#include <iostream>

template <std::size_t N, typename Predicate, typename Tuple>
consteval std::optional<std::size_t> find_if_impl(Predicate&& pred,
                                                  Tuple&& t) noexcept {
  constexpr std::size_t I = std::tuple_size_v<std::decay_t<decltype(t)>> - N;

  if constexpr (N == 0u) {
    return std::nullopt;
  } else {
    return pred(std::get<I>(t))
               ? std::make_optional(I)
               : find_if_impl<N - 1u>(std::forward<decltype(pred)>(pred),
                                      std::forward<decltype(t)>(t));
  }
}

template <typename Predicate, typename Tuple>
consteval std::optional<std::size_t> find_if(Predicate&& pred,
                                             Tuple&& t) noexcept {
  return find_if_impl<std::tuple_size_v<std::decay_t<decltype(t)>>>(
      std::forward<decltype(pred)>(pred), std::forward<decltype(t)>(t));
}

constexpr auto is_integral = [](auto&& x) noexcept {
    return std::is_integral_v<std::decay_t<decltype(x)>>;
};


int main() {
    auto t0 = std::make_tuple(9, 1.f, 2.f);
    constexpr auto i = find_if(is_integral, t0);
    if constexpr(i.has_value()) {
        std::cout << std::get<i.value()>(t0) << std::endl;
    }
}

যা এসটিএল আলগোরিদিম সন্ধানের মতো কাজ করবে বলে মনে করা হয় কিন্তু টিউপসগুলিতে এবং পুনরাবৃত্তিকে ফিরিয়ে দেওয়ার পরিবর্তে এটি একটি সংকলন টাইম প্রিকিকেটের উপর ভিত্তি করে anচ্ছিক সূচক ফেরত দেয়। এখন এই কোডটি ঠিক সূক্ষ্ম সংকলন করে এবং এটি মুদ্রণ করে

9

তবে যদি টিপলে কোনও অবিচ্ছেদ্য ধরণের উপাদান থাকে না তবে প্রোগ্রামটি সংকলন করে না, কারণ i.value () এখনও খালি alচ্ছিকভাবে ডাকা হয়। এখন তা কেন?



@ অ্যান্ডজি যা এটি ঠিক করে না, তাই না? x)
ইয়ামাহারী

উত্তর:


11

এটি ঠিক কীভাবে কনসেক্সট্রপ কাজ করে। আমরা যদি [stmt.if] / 2 পরীক্ষা করি

যদি বিবৃতিটি কনস্টেক্সপ্র হলে ফর্মের হয় তবে শর্তটির মান প্রকারের রূপে রূপান্তরিত ধ্রুবক অভিব্যক্তি হতে হবে; যদি এই বিবৃতিটি বিবৃতি হয় তবে তাকে কনটেক্সপ্রস বলা হয়। যদি রূপান্তরিত শর্তের মানটি মিথ্যা হয় তবে প্রথম সাবস্টেটমেন্টটি একটি বাতিল করা বিবৃতি, অন্যথায় দ্বিতীয় সাবস্টেটমেন্ট যদি উপস্থিত থাকে তবে তা বাতিল করা বিবৃতি। কোনও সংলগ্ন টেম্পলেটযুক্ত সত্তা ([টেম্প্পেরপ্রেস]) এর ইনস্ট্যান্টেশন চলাকালীন, যদি শর্তটি তার ইনস্ট্যান্টেশনের পরে মান-নির্ভর না হয় তবে বাতিল করা সাবস্টেটমেন্ট (যদি থাকে তবে) তাত্ক্ষণিকভাবে চালু করা হয় না। [...]

জোর আমার

সুতরাং আমরা দেখতে পাচ্ছি যে আমরা যদি কেবল কোনও টেমপ্লেটে থাকি এবং শর্তটি মূল্য-নির্ভর হয়ে থাকে তবে আমরা কেবল বাতিল করা অভিব্যক্তিটিকে মূল্যায়ন করব না। mainকোনও ফাংশন টেম্পলেট নয় তাই আইফির বডিটি এখনও সংশোধকতার জন্য সংকলক দ্বারা পরীক্ষা করা হয়।

সিপ্রেফারেন্স কনটেক্সপ্রেপ সম্পর্কে তাদের বিভাগে এটিও বলে:

যদি স্বতন্ত্র সত্তার ভিতরে যদি বিবৃতি উপস্থিত হয় এবং যদি ইনস্ট্যান্টেশনের পরে শর্তটি মূল্য-নির্ভর না হয় তবে বদ্ধ টেম্পলেটটি তাত্ক্ষণিকভাবে নিষ্ক্রিয় করা হলে ত্যাগ করা বিবৃতিটি তাত্ক্ষণিক হয় না।

template<typename T, typename ... Rest>
void g(T&& p, Rest&& ...rs) {
    // ... handle p
    if constexpr (sizeof...(rs) > 0)
        g(rs...); // never instantiated with an empty argument list.
}

কোনও টেমপ্লেটের বাইরে, একটি বাতিল করা বিবৃতি পুরোপুরি চেক করা হয়। কনস্টেক্সপ্র যদি # পূর্ব প্রস্তুতির দিকনির্দেশনার বিকল্প না হয়:

void f() {
    if constexpr(false) {
        int i = 0;
        int *p = i; // Error even though in discarded statement
    }
}

আপনি কি এর যুক্তি জানেন? দেখে মনে হচ্ছে এটি কনসেক্সট্রপিংয়ের জন্য ভাল ফিট। এছাড়াও সমাধানটি হ'ল উদাহরণস্বরূপ কোনও টেমপ্লেটে এটি মোড়ানো?
ইয়ামাহারী

@ ইয়ামাহারী কারণ সি ++ টেমপ্লেটগুলি আপনি চান তার চেয়ে কম এবং কম উভয়ই কাঠামোগত। এবং হ্যাঁ, এটি কোনও টেমপ্লেটে মোড়ানো (বা এর মতো লিখুন i.value_or(0))
ব্যারি

2
@ ইয়ামাহারী হ্যাঁ, সমাধানটি হ'ল কোডটি কোনও ফাংশন টেম্পলেটে রাখা। যুক্তি যতদূর যায়, কেন জানি না। এটি সম্ভবত জিজ্ঞাসা করা ভাল প্রশ্ন হবে।
নাথানঅলিভার

@ ব্যারি ভ্যালু_আর (0) ভাল কাজ করে তবে ক্ষেত্রে যখন টিপলের আকার 0 হয়
ইয়ামাহারী

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