विषय पर बढ़ें

अंतिम अद्यतन:2026-10-12

C++17 [[nodiscard]] एट्रिब्यूट

C++17 में [[nodiscard]] एट्रिब्यूट के पेश होने के बाद से, API लिखते समय हमारे पास एक और शक्तिशाली टूल है, जिससे उन फ़ंक्शन रिटर्न वैल्यूज़ को चिह्नित किया जाता है जिन्हें कॉल करते समय नज़रअंदाज़ नहीं करना चाहिए। इस लेख में हम [[nodiscard]] के उपयोग पर गहराई से चर्चा करेंगे और कुछ संभावित जालों पर भी ध्यान देंगे।

[[nodiscard]] क्या है?

[[nodiscard]] एक फ़ंक्शन एट्रिब्यूट है, जो कंपाइलर को बताता है कि फ़ंक्शन की रिटर्न वैल्यू को नज़रअंदाज़ नहीं किया जाना चाहिए। यह उन फ़ंक्शनों के लिए विशेष रूप से उपयोगी है जो रिटर्न वैल्यू पर निर्भर होते हैं, जैसे प्रिडिकेट फ़ंक्शन या फ़ैक्टरी फ़ंक्शन।

[[nodiscard]] का उपयोग कैसे करें?

क्लास, कंस्ट्रक्टर और एनुम पर [[nodiscard]] का उपयोग किया जा सकता है। नीचे कुछ उदाहरण दिए गए हैं:

class [[nodiscard]] A {};

class B {
public:
    [[nodiscard]] B() = default;
};

enum class [[nodiscard]] State {
    Default,
    Foo,
    Bar
};

उपरोक्त उदाहरणों में, कंपाइलर रिटर्न वैल्यू नज़रअंदाज़ होने पर चेतावनी देगा, जिससे हमें संभावित bug जल्दी पकड़ने में मदद मिलती है।

सावधान: [[nodiscard]] के जाल

यद्यपि [[nodiscard]] रिटर्न वैल्यू के अनजाने में नज़रअंदाज़ होने से प्रभावी रूप से बचा सकता है, फिर भी हमें कुछ संभावित जालों पर ध्यान देना चाहिए। एक आम जाल यह है कि [[nodiscard]] वाला फ़ंक्शन scope guard जैसा ऑब्जेक्ट लौटाए, ताकि scope के अंत में क्लीनअप ऑपरेशन निष्पादित हो (जैसे ट्रांज़ैक्शन कमिट करना)।

[[nodiscard]] ScopeGuard createScopeGuard() {
    // Implementation of a scope guard
}

// 在这里,用户可以选择忽略返回值,导致作用域立即销毁,从而失去清理效果
std::ignore = createScopeGuard();

यद्यपि [[nodiscard]] बताता है कि फ़ंक्शन की रिटर्न वैल्यू को नज़रअंदाज़ नहीं किया जाना चाहिए, लेकिन उपयोगकर्ता फिर भी std::ignore जैसे साधनों से स्पष्ट रूप से रिटर्न वैल्यू को नज़रअंदाज़ कर क्लीनअप ऑपरेशन को चक्कर दे सकते हैं।

पूरा उदाहरण

#include <tuple> // std::ignore

class [[nodiscard]] A {};
class B {
public:
    [[nodiscard]] bool isOk() const { return true; }
};

// no need for nodiscard, A is nodiscard
A foo() {
    return A();
}

// B is not nodiscard, mark it explicitly
[[nodiscard]] B bar() {
    return B();
}

int main()
{    
    foo(); // warning: ignoring temporary created by a constructor declared with 'nodiscard' attribute
    bar(); // warning

    std::ignore = foo(); // ok
    auto b = bar(); // ok
    b.isOk(); // warning
    if (b.isOk()) {} // ok
}

संबंधित विषय

टिप्पणियाँ