वेक्टर के तत्व के रूप में पूर्णांक 0 से सूचक तक निहित रूपांतरण से कैसे बचें


11

एक ऐसी स्थिति है जहाँ मैं JSON में एक कुंजी के लिए पथ के सभी नोड नाम एकत्र करना चाहता हूं। सरणी इंडेक्स "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>>?
5

क्या आप nullptrभी मना करना चाहते हैं?
Jarod42

@bolov शुरुआत में मैं इन नोड्स नामों को एक JSON विश्लेषण इंटरफ़ेस में पारित करने के लिए विचार करता हूं, जो इनपुट के रूप में C- शैली चार * का उपयोग करता है, लेकिन यह यहाँ सीमित नहीं है। मैंने परीक्षण किया है, std का उपयोग करते हुए :: वेक्टर <std :: string >> अभी भी 0 स्वीकार करता है जब संकलित करता है, लेकिन जब मशीन चलती है, तो दुर्घटनाग्रस्त हो जाती है, मेरी मशीन GCC की रिपोर्ट "basic_string :: _ M_construct null मान्य नहीं है"।
रिस्टीचू

@ Jarod42 हां, सी-स्टाइल स्ट्रिंग शाब्दिक क्या है।
ऋतूभू

जवाबों:


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

Hindsight में C ++ में निहित कई रूपांतरण दुर्भाग्यपूर्ण हैं, यह उनमें से एक है।

विचार करने के लिए एक विकल्प -Wzero-as-null-pointer-constantgcc और clang पर है। सावधान रहें क्योंकि इससे मानक कार्यक्रमों का व्यवहार बदल जाता है और यदि विश्व स्तर पर सक्षम हो तो कुछ अनपेक्षित प्रभाव पड़ सकते हैं।

g ++ - मैं 0 से सूचक प्रकारों में अंतर्निहित रूपांतरण को कैसे अक्षम करूं?

कौन सी क्लैंग चेतावनी GCC से Wzero-as-null-pointer-constant के बराबर है?


3

मुझे मिकेल रिक्लिस्की का जवाब पसंद है । हालाँकि, पहले से ही गाइडलाइन सपोर्ट लाइब्रेरी में एक समाधान मौजूद है :

gsl::not_null

मैं जीएसएल की अत्यधिक अनुशंसा करता हूं। यह कई C ++ विशेषज्ञों द्वारा निर्मित और समर्थित है, ब्रेज़न स्ट्रॉस्ट्रुप खुद और उनके बीच हर्ब सटर। और सी ++ कोर दिशानिर्देश सक्रिय रूप से संकलक चेतावनी और स्थिर विश्लेषक में एकीकृत किए जा रहे हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.