সুস্পষ্ট (বুল) জন্য ইউজকেস কি


24

সি ++ 20 প্রবর্তিত সুস্পষ্ট (বুল) যা শর্তাধীনভাবে কোনও নির্মাণকারী সুস্পষ্ট করা হয়েছে কিনা তা সংকলন-সময় নির্বাচন করে।

নীচে একটি উদাহরণ যা আমি এখানে পেয়েছি ।

struct foo {

  // Specify non-integral types (strings, floats, etc.) require explicit construction.

  template <typename T>

  explicit(!std::is_integral_v<T>) foo(T) {}

};

foo a = 123; // OK

foo b = "123"; // ERROR: explicit constructor is not a candidate (explicit specifier evaluates to true)

foo c {"123"}; // OK

কেউ কি আমাকে explicit (bool)ব্যবহার ছাড়া অন্য কোনও ইউসকেস বলতে পারেন std::is_integral?


1
একটি উদাহরণ হ'ল tupleএই বৈশিষ্ট্যটির মতো শর্তসাপেক্ষে সুস্পষ্ট নির্মাতাদের বাস্তবায়ন করা অনেক সহজ হয়ে যায় ।
প্রিটোরিয়ান

1
যথাযথ উত্তর নয়, তবে আপনি কাগজে প্রেরণাটিও দেখে নিতে পারেন যা এটি চালু করেছে: wg21.link/p0892
এন শেড

উদাহরণ: এটি (ধারণাগুলি সহ) শর্তাধীন সরবরাহিত শর্তাধীন সুস্পষ্ট অনুলিপি নির্মাণকারীকে 3 থেকে 0 পর্যন্ত বাস্তবায়নের জন্য প্রয়োজনীয় সংখ্যার বেস ক্লাসগুলি হ্রাস করে
এলএফ

উত্তর:


21

প্রেরণা নিজেই কাগজে দেখা যায় ।

শর্তসাপেক্ষে নির্মাতাদের তৈরি করার প্রয়োজন রয়েছে। এটি, আপনি চান:

pair<string, string> safe() {
    return {"meow", "purr"}; // ok
}

pair<vector<int>, vector<int>> unsafe() {
    return {11, 22}; // error
}

পূর্বেরটি ঠিক আছে, যারা নির্মাতারা অন্তর্নিহিত। তবে আধুনিকগুলি খারাপ হবে, যারা নির্মাতারা explicit। সি ++ 17 (বা ধারণাগুলি সহ সি ++ 20) দিয়ে, এই কাজটি করার একমাত্র উপায় দুটি নির্মাণকারীর লেখা - একটি explicitএবং একজন নয়:

template <typename T1, typename T2>
struct pair {
    template <typename U1=T1, typename U2=T2,
        std::enable_if_t<
            std::is_constructible_v<T1, U1> &&
            std::is_constructible_v<T2, U2> &&
            std::is_convertible_v<U1, T1> &&
            std::is_convertible_v<U2, T2>
        , int> = 0>
    constexpr pair(U1&&, U2&& );

    template <typename U1=T1, typename U2=T2,
        std::enable_if_t<
            std::is_constructible_v<T1, U1> &&
            std::is_constructible_v<T2, U2> &&
            !(std::is_convertible_v<U1, T1> &&
              std::is_convertible_v<U2, T2>)
        , int> = 0>
    explicit constexpr pair(U1&&, U2&& );    
};  

এগুলি প্রায় সম্পূর্ণ নকল - এবং এই নির্মাতাদের সংজ্ঞাটি অভিন্ন হবে।

এর মাধ্যমে explicit(bool), আপনি কেবলমাত্র একটি একক নির্মাণকারী লিখতে পারেন - নির্মাণের শর্তাধীন স্পষ্ট অংশের সাথে কেবল স্থানীয়- explicitস্পেসিফায়ারে স্থানীয়করণ করেছেন :

template <typename T1, typename T2>
struct pair {
    template <typename U1=T1, typename U2=T2,
        std::enable_if_t<
            std::is_constructible_v<T1, U1> &&
            std::is_constructible_v<T2, U2>
        , int> = 0>
    explicit(!std::is_convertible_v<U1, T1> ||
        !std::is_convertible_v<U2, T2>)
    constexpr pair(U1&&, U2&& );   
};

এই উদ্দেশ্যটির সাথে আরও ভাল মিলছে, লেখার জন্য অনেক কম কোড এবং ওভারলোড রেজোলিউশনের সময় সংকলকটির জন্য কম কাজ (যেহেতু এর মধ্যে বেছে নিতে কম কনস্ট্রাক্টর রয়েছে)।


1
সি ++ 20 এছাড়াও enable_if_tসম্ভবত ধারণাগুলি ব্যবহার করে, অংশটিকে একটি প্রাকৃতিক এবং সহজ সীমাবদ্ধতায় পরিবর্তন করার ক্ষমতা সরবরাহ করে । তবে এটি এই প্রশ্নের পয়েন্টের পাশে।
aschepler

2

আর একটি সম্ভাব্য ব্যবহার যা আমি দেখছি তা হ'ল ভ্যারিয়্যাডিক টেম্পলেট সহ:

এটি সাধারণত ডিফল্টরূপে ভাল explicitকেবলমাত্র একটি যুক্তি দিয়ে কনস্ট্রাক্টরের (রূপান্তরটি না চাইলে)।

সুতরাং

struct Foo
{
    template <typename ... Ts>
    explicit(sizeof...(Ts) == 1) Foo(Ts&&...);

    // ...
};

0

explicitশর্তাধীন প্রয়োজনের জন্য আমি কোনও ব্যবহারের ক্ষেত্রে দেখতে পেতাম যখন ইনপুটটি ভিউ-জাতীয় ধরণের হতে পারে (কাঁচা পয়েন্টার,std::string_view ) যা কলটি করার পরে নতুন অবজেক্টটি ধরে রাখবে (কেবলমাত্র দৃষ্টিভঙ্গিটি অনুলিপি করবে না, নির্ভর করে এটি নির্ভর করে দেখা বস্তুর আজীবন), বা এটি কোনও মানের মতো ধরণের হতে পারে (কোনও অনুলিপিটির মালিকানা গ্রহণ করে, কোনও বহিরাগত আজীবন নির্ভরতা ছাড়াই)।

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

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