2016-02-01 7 views
7

का उपयोग करके हस्ताक्षरित और हस्ताक्षरित चर के लिए एक वैरिएडिक कन्स्ट्रक्टर बनाएं, मैं किसी भी अभिन्न प्रकार का उपयोग करके कक्षा के लिए एक कन्स्ट्रक्टर बनाना चाहता हूं, लेकिन हस्ताक्षरित और हस्ताक्षरित के बीच अंतर करता हूं। मैं नहीं चाहता कि यह वर्ग पर ही एक टेम्पलेट हो। निम्नलिखित काम नहीं कर रहा है। विजुअल स्टूडियो सिर्फ यह कह रहा है कि कोई तर्क मेल नहीं खाएगा।सक्षम_if

class Thing{ 
public: 
    template<typename Integral> 
    Thing(
     typename std::enable_if< 
      std::is_integral<Integral>::value && 
      !std::is_same<Integral,bool>::value && 
      std::is_signed<Integral>::value 
      ,Integral 
     >::type num 
    ){ 
     //constructor using signed variable as input 
    } 
    template<typename Integral> 
    Thing(
     typename std::enable_if< 
      std::is_integral<Integral>::value && 
      !std::is_same<Integral,bool>::value && 
      !std::is_signed<Integral>::value//notice this is different 
      ,Integral 
     >::type num 
    ){ 
     //constructor using unsigned variable as input 
    } 
}; 
+1

यह काम नहीं कर रहा है? यह क्या कर रहा है :) – erip

+0

'सार्वजनिक' कीवर्ड की कमी कम से कम कोड की कोशिश करते समय मुझे प्राप्त होने वाली पहली त्रुटि के बारे में कम से कम कुछ कहता है ... – skypjack

उत्तर

5

हमें SFINAE को टेम्पलेट में स्थानांतरित करने की आवश्यकता है। अगर हम

class Thing{ 
public: 
    template<typename Integral, typename std::enable_if< 
      std::is_integral<Integral>::value && 
      !std::is_same<Integral,bool>::value && 
      std::is_signed<Integral>::value 
      ,Integral>::type* = nullptr> // will fail if type does not exist 
    Thing(Integral i) 
//  ^use Integral type here 
    { 
     std::cout << "signed\n"; 
    } 
    template<typename Integral, typename std::enable_if< 
      std::is_integral<Integral>::value && 
      !std::is_same<Integral,bool>::value && 
      !std::is_signed<Integral>::value//notice this is different 
      ,Integral>::type* = nullptr> 
    Thing(Integral i) 
    { 
     std::cout << "unsigned\n"; 
    } 
}; 

int main() 
{ 
    int a = 10; 
    Thing b(a); 
    unsigned int c = 10; 
    Thing d(c); 
} 

का उपयोग हम

signed 
unsigned 

Live Example

मिल रहा निर्माणकर्ता public बनाने के लिए के रूप में वे private डिफ़ॉल्ट रूप से थे।

3

समस्या यह है कि प्रकार एक non-deduced context दिखाए जाते हैं इसलिए संकलक std::is_integral<Integral>::value की तरह कुछ से यह अनुमान नहीं कर सकता है। ऐसा करें:

#include <iostream> 
#include <type_traits> 

class Thing{ 
public: 
    template<typename Integral> 
    Thing(Integral num, 
     typename std::enable_if< 
      std::is_integral<Integral>::value && 
      !std::is_same<Integral,bool>::value && 
      std::is_signed<Integral>::value 
      ,Integral 
     >::type* = nullptr 
    ){ 
     std::cout << "signed\n"; 
     //constructor using signed variable as input 
    } 

    template<typename Integral> 
    Thing(Integral num, 
     typename std::enable_if< 
      std::is_integral<Integral>::value && 
      !std::is_same<Integral,bool>::value && 
      !std::is_signed<Integral>::value//notice this is different 
      ,Integral 
     >::type* = nullptr 
    ){ 
     std::cout << "unsigned\n"; 
     //constructor using unsigned variable as input 
    } 
}; 

int main() 
{ 
    int x{}; 
    unsigned int y{}; 
    Thing thing1(x); 
    Thing thing2(y); 
} 

Live on Coliru

साइड नोट: अपने कंस्ट्रक्टर्स public के रूप में अन्यथा आप अपने वस्तुओं का दृष्टांत नहीं कर सकते हैं।

+0

आप चुपचाप यह इंगित करते हुए कि ओपी को सीटीर्स को 'सार्वजनिक' बनाने की भी आवश्यकता है :-) – AndyG

+0

@AndyG मैं वास्तव में इसका उल्लेख करना भूल गया, लेकिन उन्हें मेरे कोड में 'सार्वजनिक' बना दिया;) – vsoftco

+0

व्यक्तिगत रूप से मैं टेम्पलेट तर्कों में 'enable_if' रखना पसंद करूंगा:' टेम्पलेट :: मूल्य) && (! std :: is_same :: मूल्य) && (std :: is_signed :: मूल्य), पूर्णांक> :: प्रकार = 0> बात (टी _in) 'लेकिन यह वही है – AndyG