কোনও ভেক্টরের উপাদান হিসাবে পূর্ণসংখ্যা 0 থেকে পয়েন্টার পর্যন্ত অন্তর্নিহিত রূপান্তরগুলি কীভাবে এড়ানো যায়


11

এমন একটি পরিস্থিতি রয়েছে যেখানে আমি জেএসএনে একটি কী এর কাছে সমস্ত নোডের নাম সংগ্রহ করতে চাই। অ্যারে সূচক "0", "1" এর শর্তটি বিবেচনা করার অনুমতিও রয়েছে তবে উদ্ধৃতিগুলি ভুলে যাওয়া সহজ, যা শ্রদ্ধাবোধের পরে ক্রাশ হতে পারে। সুতরাং আমি এই প্রত্যাখ্যান করতে চাই। উদাহরণ:

#include <vector>
#include <iostream>

int func(const std::vector<const char*>& pin) {
    return pin.size();
}

int main() {
    // {"aname", "3", "path", "0"} wanted but this still compile
    std::cout << func({"aname", "3", "path", 0}) << std::endl;
}

আমি এটি খুঁজে পেয়েছি এবং চেষ্টা করেছি কী করে আমি অ-নির্মাণমূলক কার্যগুলিতে অন্তর্নিহিত রূপান্তরগুলি এড়াতে পারি? নিম্নলিখিত হিসাবে:

#include <vector>
#include <iostream>

int func(const std::vector<const char*>& pin) {
    return pin.size();
}

template<typename T>
int func(T pin) = delete;

int main() {
    std::cout << func({"aname", "3", "path", 0}) << std::endl;
}

সংকলকটি তখনও আমাকে বুঝতে পারেনি।

যেকোনো পরামর্শ?
পরিভাষা এবং অনুমানের কোনও অপব্যবহারটি দয়া করে নির্দেশ করুন, আপনাকে ধন্যবাদ!


আপনি std::vector<const char*>পরিবর্তে ব্যবহার করার কারণ আছে std::vector<std::string>>?
বলভ

আপনি কি বারণ করতে চান nullptr?
জারোড 42

@ বলভ শুরুতে আমি এই নোডের নামগুলি একটি JSON বিশ্লেষণ ইন্টারফেসে পাস করার কথা বিবেচনা করি, যা সি-স্টাইল চর * ইনপুট হিসাবে ব্যবহার করে, তবে এটি এখানে সীমাবদ্ধ নয়। আমি পরীক্ষা করেছি, std :: ভেক্টর <std :: স্ট্রিং ব্যবহার করে >> এখনও কম্পাইল করার সময় 0 টি গ্রহণ করে, তবে রান করার সময় ক্র্যাশ হয়ে গেছে, আমার মেশিনে জিসিসি "বেসিক_স্ট্রিং :: _ এম_স্ট্রাক্ট নাল বৈধ নয়" বলে প্রতিবেদন করেছে।
rustyhu

@ জারোড 42 হ্যাঁ, সি-স্টাইলের স্ট্রিংটি আক্ষরিক কী চাই।
rustyhu

উত্তর:


10

এটার মতো কিছু? এটি আপনার প্রস্তাবিত ওভারলোড সমাধানের সাথে খুব মিল, তবে ভেক্টরের ধরণটি মোড়ানো প্রয়োজন। আপনি যদি আক্ষরিক প্রদান করেন তবে তা বিল্ড করতে ব্যর্থ হয় 0কারণ মোছা কনস্ট্রাক্টর ওভারলোড বেছে নেওয়া হয়েছে।

#include <memory>
#include <new>
#include <vector>
#include <iostream>
using std::vector;

template<typename T>
struct no_zero {
        no_zero(T val) : val(val) {}
        no_zero(int val) = delete;
        operator T() { return val; }
        T val;
};

int func(const vector<no_zero<const char*> >& pin) {
    return pin.size();
}

int main() {
    // {"aname", "3", "path", "0"} wanted but this still compile
    std::cout << func({"aname", "3", "path", 0}) << std::endl;
}

4

অন্ধকারে সি ++ তে অন্তর্নিহিত অনেকগুলি রূপান্তর দুর্ভাগ্যজনক, এটি তাদের মধ্যে একটি।

বিবেচনার জন্য একটি বিকল্প হ'ল -Wzero-as-null-pointer-constantজিসিসি এবং বিড়ম্বনা। সতর্কতা অবলম্বন করুন কারণ এটি স্ট্যান্ডার্ড প্রোগ্রামগুলির আচরণের পরিবর্তন করে এবং বিশ্বব্যাপী সক্ষম করা থাকলে কিছু অযাচিত প্রভাব ফেলতে পারে।

g ++ - আমি কীভাবে 0 থেকে পয়েন্টার ধরণের রূপান্তরকে অক্ষম করব?

কোন ধরণের সতর্কতা জিসিসি থেকে ওয়াজারো-আস-নাল-পয়েন্টার-ধ্রুবকের সমান?


3

আমি মাইকেল রাইচলস্কির উত্তরটি পছন্দ করি । তবে ইতিমধ্যে গাইডলাইন সহায়তা লাইব্রেরিতে একটি সমাধান রয়েছে :

gsl::not_null

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

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