2012-11-10 13 views
5

unique_lockconstructors में से कुछ में सी ++ 11 एक कुछ classes एक ध्वज की तरह, यानीसी ++ 11 खाली झंडा कक्षाएं

auto lock = std::unique_lock<std::mutex> lock(m, std::defer_lock); 

जहां std::defer_lock

struct defer_lock {} 

के रूप में परिभाषित किया गया है पारित कर सकते हैं ऐसा क्यों किया जाता है, न कि enum के साथ?

मैं एक छोटे से कोड नमूना करने के लिए इस लागू करने की कोशिश, लेकिन मैं इसे संकलन नहीं मिल सका:

class A {}; 
void foo(A a) {} 

int main() { 
    foo(A); // error: 'A' does not refer to a value 
} 

जब मैं foo(A()); यह काम करता है की तरह कोष्ठकों शब्दों में कहें, लेकिन मैं करने के लिए अंतर दिखाई नहीं देता एसटीएल यह अलग तरीके से क्यों व्यवहार करता है?

+5

[ऐसा लगता है कि 'std :: defer_lock' वास्तव में 'std :: defer_lock_t'] का एक उदाहरण है (http://en.cppreference.com/w/cpp/thread/lock_tag)। मेरा अनुमान है कि इसका उपयोग क्यों किया जाता है क्योंकि यह एक enum मान (बूट करने के लिए रन-टाइम पर) पर बदसूरत स्विच-केस की बजाय संकलक को ओवरलोड का चयन करने देता है। – Cameron

उत्तर

9

enum के बजाय किसी निश्चित ऑपरेशन को चिह्नित करने के लिए एक अलग प्रकार का उपयोग करने से कोड पथ की पसंद रन-टाइम पसंद के बजाय संकलन-समय विकल्प ले रही है। विभिन्न कार्यों के कार्यान्वयन भी काफी अलग हो सकते हैं।

+6

और इसे "टैग प्रेषण" कहा जाता है। – Xeo

5

वास्तव में, std::defer_lock परिभाषित नहीं है के रूप में आप लिखते हैं, लेकिन

constexpr std::defer_lock_t defer_lock = std::defer_lock_t(); 

क्यों अपने संस्करण "नकल उतार" (बुरी तरह) मानक पुस्तकालय परिभाषा काम नहीं करता है कि के रूप में; उदाहरण के लिए अपनी परिभाषा बदलें।

struct A {} A; 

और यह काम करेगा। (या, थोड़ा अधिक आकर्षक struct A_t {} A)

4

मानक पुस्तकालय में वास्तविक कोड

struct defer_lock_t {}; 
constexpr defer_lock_t defer_lock {}; 

है पहली पंक्ति कोई सदस्यों के साथ एक वर्ग को परिभाषित करता। दूसरी पंक्ति उस प्रकार की वस्तु को परिभाषित करती है। ऑब्जेक्ट फ़ंक्शन कॉल में उपयोग किया जाता है।