ল্যাম্বডায় স্ট্যাটিক_সেসার্টের সাথে কনস্টেক্সপ্র হলে, কোন সংকলকটি সঠিক?


13

আমরা একটি ব্যবহার করতে চান, তখন static_assertএকটি if constexprআমরা শর্ত কিছু টেমপ্লেট প্যারামিটার উপর নির্ভরশীল করা আবশ্যক। মজার বিষয় হল, কোডটি যখন ল্যাম্বডায় মোড়ানো হয় তখন জিসিসি এবং কলঙ্কগুলি দ্বিমত হয়।

নিম্নলিখিত কোডটি জিসিসির সাথে সংকলন করে, তবে ঝনঝনানি দৃsert়তাটিকে ট্রিগার করে, এমনকি যদি এটি if constexprসত্য নাও হয়।

#include <utility>

template<typename T> constexpr std::false_type False;

template<typename T>
void foo() {

    auto f = [](auto x) {
        constexpr int val = decltype(x)::value;
        if constexpr(val < 0) {
            static_assert(False<T>, "AAA");
        }
    };

    f(std::integral_constant<int, 1>{});
}

int main() {
    foo<int>();
}

লাইভ উদাহরণ এখানে

এটি সহজেই বিকল্প False<T>দ্বারা স্থির করা যেতে পারে False<decltype(x)>

সুতরাং প্রশ্নটি: কোন সংকলকটি সঠিক? আমি ধরে নিয়েছিলাম যে সিসিটি সঠিক, কারণ অবস্থার static_assertউপর নির্ভরশীল T, তবে আমি নিশ্চিত নই।


এটি একই ধরণের প্রশ্ন জিজ্ঞাসা করে তবে বিপরীত দিক থেকে আসছে: স্ট্যাকওভারফ্লো / প্রশ্নগুলি / 59393908/ … 8
নাথান অলিভার

1
@mfnx পুনরুত্পাদন করতে পারবেন না । আপনি একটি উদাহরণ ভাগ করতে পারেন?
নাথান অলিভার

2
আমি উভয়ই ঠিক বলেছেন (অসুস্থভাবে গঠিত এনডিআর): ল্যাম্বডারের অভ্যন্তরের static_assert(False<int>, "AAA");সমতুল্য static_assert(false, "AAA");
জারোড 42

2
@mfnx আপনি ধ্রুবকের মান পরিবর্তন করেছেন। ধ্রুবক f(std::integral_constant<int, 1>{});ওয়ানডবক্স যেখানে ওপি'র উদাহরণ ব্যবহার করা দৃsert়তাটিকে ট্রিগার করে না: ভ্যান্ডবক্স.অর্গ
ইউএফওয়াইআমওয়াইটিটি 1

1
@ নাথান অলিভার হ্যাঁ আপনি ঠিক বলেছেন, গোলমাল করার জন্য দুঃখিত। মনে হচ্ছে জিসিসি ঠিক ঠিক ঠিক যেমন কনস্টেক্সপ্রের কোডটি বাতিল করা উচিত যদি ধ্রুবক> = 0;
এমএফএনএক্স

উত্তর:


1

থেকে [stmt.if] / 2 (জোর খনি)

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

পড়ার ফলে কেউ ভাবেন যে স্থির দৃsert়তা বাদ দেওয়া হবে, তবে এটি এমন নয়।

স্থির দাবী টেম্পলেটটির প্রথম পর্যায়ে ট্রিগার করা হয় কারণ সংকলক জানেন যে এটি সর্বদা মিথ্যা।

থেকে [temp.res] / 8 (জোর খনি)

কোনও ইনস্ট্যান্টেশন করার আগে কোনও টেম্পলেটটির বৈধতা পরীক্ষা করা যেতে পারে। [ দ্রষ্টব্য: কোন নামগুলি টাইপ নাম রয়েছে তা জেনে প্রতিটি টেমপ্লেটের সিনট্যাক্সটিকে এভাবে পরীক্ষা করা যায়। - শেষ দ্রষ্টব্য ] প্রোগ্রামটি দুর্গঠিত, কোনও ডায়াগনস্টিকের প্রয়োজন নেই, যদি:

  • (৮.১) কোনও টেম্পলেট এবং টেমপ্লেট ইনস্ট্যান্ট না করা হলে কোনও টেম্পলেট বা কনস্টেক্সপ্রের সাবস্টেটমেন্টের জন্য কোনও বৈধ বিশেষীকরণ তৈরি করা যাবে না , বা

[...]

হ্যাঁ, আপনার False<T>উপর নির্ভর করে T। সমস্যাটি হ'ল জেনেরিক ল্যাম্বদা নিজেই একটি টেম্পলেট এবং False<T>ল্যাম্বদার কোনও টেম্পলেট প্যারামিটারের উপর নির্ভর করে না।

একটি জন্য Tযে False<T>মিথ্যা স্ট্যাটিক জাহির সবসময় শত্রুর হাতে তুলে দেবে, সেটা ব্যাপার যা ফর্মা যুক্তি ল্যামডা পাঠানো হয়।

সংকলক দেখতে পাবে যে টেমপ্লেটের কোনও ইনস্ট্যান্টেশনের জন্য operator(), স্ট্যাটিক দাবী সর্বদা বর্তমান টি এর জন্য ট্রিগার করবে Hence তাই সংকলক ত্রুটি।

এর একটি সমাধান এর উপর নির্ভর করবে x:

template<typename T>
void foo() {

    auto f = [](auto x) {
        if constexpr(x < 0) {
            static_assert(False<decltype(x)>, "AAA");
        }
    };

    f(std::integral_constant<int, 1>{});
}

সরাসরি উদাহরণ


13

এখানে সাধারণ নিয়মটি হ'ল [অস্থায়ী।] / ৮ :

প্রোগ্রামটি দুর্গঠিত, কোনও ডায়াগনস্টিকের প্রয়োজন নেই, যদি: কোনও টেম্পলেটের মধ্যে বিবৃতি এবং টেমপ্লেট ইনস্ট্যান্ট না করা হয় তবে কোনও টেম্পলেট বা কনস্টেক্সপ্রের সাবস্টেটমেন্টের জন্য কোনও বৈধ বিশেষীকরণ তৈরি করা যায় না if

একবার তাত্ক্ষণিকভাবে চালিত হয়ে গেলে foo<T>, static_assertআপনার কাছে থাকা আর আর নির্ভরশীল নয়। এটি হয়ে যায় static_assert(false)- জেনেরিক ল্যাম্বদার কল অপারেটরের সমস্ত সম্ভাব্য তাত্পর্যগুলির জন্য f। এটি দুর্গঠিত, ডায়াগনস্টিকের প্রয়োজন নেই। ঝনঝন রোগ নির্ণয় করে, জিসিসি তা করে না। দুটোই সঠিক.

দ্রষ্টব্য যে static_assertএখানে যে বিষয়টি বাতিল করা হয়েছে তা বিবেচ্য নয়।

এটি সহজেই বিকল্প False<T>দ্বারা স্থির করা যেতে পারে False<decltype(x)>

এটি static_assertজেনেরিক ল্যাম্বডায় নির্ভরশীল রাখে এবং এখন আমরা এমন একটি রাজ্যে পৌঁছে গেলাম যেখানে অনুমানগতভাবে কোনও বৈধ বিশেষীকরণ হতে পারে, সুতরাং আমরা আর অসুস্থ নই, এনডিআর।

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