2017-10-05 15 views
19

मैं अस्थिर प्रकारों पर एक विशिष्ट संचालन को अस्वीकार करने की कोशिश कर रहा हूं। इसे पूरा करने के लिए मैं std::is_volatile का उपयोग करने की कोशिश कर रहा हूं, लेकिन नीचे दिया गया कोड त्रुटियों के बिना संकलित है, जो मैं नहीं चाहता हूं।std :: is_volatile का उपयोग कैसे करें?

is_volatile::valueझूठी नीचे दिए गए मामले में क्यों है?

#include <type_traits> 

template<typename T> 
inline void DoStuff(T val) { 
    static_assert(!std::is_volatile<T>::value, "No volatile types plz"); 
    //... 
} 

int main() { 
    volatile char sometext[261]; 
    DoStuff(sometext); 
} 
+0

यह है कि टेम्पलेट तर्क कटौती कैसे काम करता है - क्वालीफायर मूल्य-मूल्य पैरामीटर प्रकारों का हिस्सा नहीं हैं। यह अनिवार्य रूप से वही है: 'अस्थिर int src = ...; int n = src; '। ध्यान दें कि 'src' की योग्यता के बारे में कुछ भी नहीं जानता है। दूसरे शब्दों में, lvalue-to-rvalue रूपांतरण क्वालीफायर को छोड़ देता है। –

+0

@KerrekSB शायद आपने अनदेखा किया है कि एक सरणी को तर्क –

+0

@ एमएम: नहीं दिया गया है, जो केवल विवरणों को जटिल करता है, लेकिन मूल मुद्दा बनी हुई है। –

उत्तर

28

समस्या यह है कि टी एक volatile प्रकार बिल्कुल नहीं है। यह volatile char* है। एक मिनट रुको, आप कहते हैं, मैं वहां volatile देखता हूं। सच है, लेकिन इस पर विचार करें: char* volatile एक अस्थिर प्रकार है। volatile char* नहीं है। यह एक अस्थिर char सरणी के लिए एक अस्थिर सूचक है।

समाधान: std::is_volatile<typename std::remove_pointer<T>::type>

+4

बेहतर समाधान: 'इनलाइन शून्य DoStuff (टी * वैल) '? 'टी' को स्वीकार करने के बाद पॉइंटर को अलग करना 'टी * 'स्वीकार करने से कम समझदार लगता है। – Yakk

1

क्योंकि फ़ंक्शन मान द्वारा इसके तर्क को स्वीकार करते हैं, मूल तर्क की सीवी-योग्यता खो जाती है।

संदर्भ द्वारा यह स्वीकार करना:

void DoStuff(T& val) 
+0

उदाहरण तर्क को ध्यान में रखते हुए एक सरणी है, 'टी * वैल' अधिक समझ सकता है (लेकिन हम संदर्भ खो रहे हैं) – MSalters

9

जब मूल्य द्वारा सरणी पारित करने के लिए कोशिश कर रहा है, वह अपने पहले तत्व के लिए सूचक में decays।

इसका मतलब है कि val वास्तव में int volatile * है। इस प्रकार, यह एक अस्थिर int को इंगित करता है, लेकिन यह स्वयं अस्थिर नहीं है। इसलिए, std::is_volatile झूठी वापसी करता है।

आप संदर्भ द्वारा सरणी में ले जाने का प्रयास कर सकते हैं, या std::remove_pointer का उपयोग कर सकते हैं।

संबंधित मुद्दे