2014-10-07 10 views
6

मेरे पास एक आंत महसूस नहीं है VS2012 इस पर गलत है, लेकिन मुझे यकीन नहीं है।प्रोग्राम विजुअल स्टूडियो 2012 में चलता है लेकिन ideone.com

this question देखने के बाद, मुझे ऐसा कुछ लागू करने की कोशिश करने की तरह लगा।

मेरा संस्करण विजुअल स्टूडियो 2012 पर ठीक काम करता है, लेकिन Ideone पर संकलित भी नहीं करता है।

#include <iostream> 
#include <string> 

template <class In, class Out> 
struct Pipe 
{ 
    typedef In in_type ; 
    typedef Out out_type ; 

    In in_val ; 

    Pipe (const in_type &in_val = in_type()) : in_val (in_val) 
    { 
    } 

    virtual auto operator()() const -> out_type 
    { 
     return out_type() ; 
    } 
}; 

template <class In, class Out, class Out2> 
auto operator>> (const Pipe <In, Out> &lhs, Pipe <Out, Out2> &rhs) -> Pipe <Out, Out2>& 
{ 
    rhs = lhs() ; 
    return rhs ; 
} 

template <class In, class Out> 
auto operator>> (const Pipe <In, Out> &lhs, Out &rhs) -> Out& 
{ 
    rhs = lhs() ; 
    return rhs ; 
} 

यहाँ कुछ परीक्षण वर्ग हैं::

struct StringToInt : public Pipe <std::string, int> 
{ 
    StringToInt (const std::string &s = "") : Pipe <in_type, out_type> (s) 
    { 
    } 

    auto operator()() const -> out_type 
    { 
     return std::stoi (in_val) ; 
    } 
}; 

struct IntSquare : public Pipe <int, int> 
{ 
    IntSquare (int n = 0) : Pipe <in_type, out_type> (n) 
    { 
    } 

    auto operator()() const -> out_type 
    { 
     return in_val * in_val ; 
    } 
}; 

struct DivideBy42F : public Pipe <int, float> 
{ 
    DivideBy42F (int n = 0) : Pipe <in_type, out_type> (n) 
    { 
    } 

    auto operator()() const -> out_type 
    { 
     return static_cast <float> (in_val)/42.0f ; 
    } 
}; 

और यहाँ चालक है:

यहाँ मेरी मुख्य इंटरफेस है

int main() 
{ 
    float out = 0 ; 
    StringToInt ("42") >> IntSquare() >> DivideBy42F() >> out ; 
    std::cout << out << "\n" ; 

    return 0 ; 
} 

Ideone टेम्पलेट कटौती के बारे में शिकायत कर रहा है और यह सही operator>> उम्मीदवार समारोह खोजने में असमर्थ है:

prog.cpp: In function ‘int main()’: 
prog.cpp:75:21: error: no match for ‘operator>>’ (operand types are ‘StringToInt’ and ‘IntSquare’) 
    StringToInt ("42") >> IntSquare() >> DivideBy42F() >> out ; 
        ^
prog.cpp:75:21: note: candidates are: 
prog.cpp:23:6: note: Pipe<Out, Out2>& operator>>(const Pipe<In, Out>&, Pipe<Out, Out2>&) [with In = std::basic_string<char>; Out = int; Out2 = int] 
auto operator>> (const Pipe <In, Out> &lhs, Pipe <Out, Out2> &rhs) -> Pipe <Out, Out2>& 
    ^
prog.cpp:23:6: note: no known conversion for argument 2 from ‘IntSquare’ to ‘Pipe<int, int>&’ 
prog.cpp:30:6: note: template<class In, class Out> Out& operator>>(const Pipe<In, Out>&, Out&) 
auto operator>> (const Pipe <In, Out> &lhs, Out &rhs) -> Out& 
    ^
prog.cpp:30:6: note: template argument deduction/substitution failed: 
prog.cpp:75:35: note: deduced conflicting types for parameter ‘Out’ (‘int’ and ‘IntSquare’) 
    StringToInt ("42") >> IntSquare() >> DivideBy42F() >> out ; 

कौन सा संकलक सही है? यदि विचार सही है, तो क्या इस कोड के लिए कोई आसान फिक्स है?

+3

(* शायद डुप्लिकेट? *) से संबंधित: [गैर-कॉन्स्ट संदर्भ अस्थायी, विजुअल स्टूडियो बग से बंधे हैं?] (Http://stackoverflow.com/q/16380966/1708801) ... मूल रूप से gcc यहां सही है । यदि आप विजुअल स्टूडियो में '/ Za' के साथ बनाते हैं तो यह भी असफल हो जाएगा, [इसे लाइव देखें] (http://rextester.com/GYMOJ23021)। –

+3

इस सवाल को बंद करने के लिए मतदान करने के लिए मूर्खतापूर्ण है * यह कोड क्यों काम नहीं कर रहा है *। परीक्षण छोटा हो सकता है लेकिन यह संकलक के बीच विवादित परिणामों के साथ एक पूर्ण परीक्षण केस है और यह निश्चित रूप से सही नहीं है जो कि सही है। –

उत्तर

2

विचार (वास्तव में, जीसीसी) यहां सही है। विजुअल स्टूडियो में, यह एक कुख्यात विस्तार के कारण संकलित करता है जो अस्थायी को गैर-कॉन्स लैल्व संदर्भों (मानक वर्जित करता है) से जुड़ने की अनुमति देता है।

मैं मानक सी में इस का समाधान करने के लिए कई संभव तरीके ++ देखें:

एक, पाइप लाइन चरणों के लिए temporaries का उपयोग नहीं करते:

int main() 
{ 
    float out = 0 ; 
    StringToInt stage1("42"); 
    IntSquare stage2; 
    DivideBy24F stage3; 
    stage1 >> stage2 >> stage3 >> out ; 
    std::cout << out << "\n" ; 

    return 0 ; 
} 

दो, एक "रहने" समारोह बनाने (के विपरीत std::move), और कहा कि का उपयोग करें:

template <class T> 
T& stay(T &&x) { return x; } 

int main() 
{ 
    float out = 0 ; 
    stay(StringToInt ("42")) >> stay(IntSquare()) >> stay(DivideBy42F()) >> out ; 
    std::cout << out << "\n" ; 

    return 0 ; 
} 

तीन, एक r-मूल्य संदर्भ लेने operator >> की एक अधिभार प्रदान करते हैं:

template <class In, class Out, class Out2> 
auto operator>> (const Pipe <In, Out> &&lhs, Pipe <Out, Out2> &&rhs) -> Pipe <Out, Out2>& 
{ 
    return lhs >> rhs; // Notice that lhs and rhs are lvalues! 
} 

बेशक, आदर्श रूप से आप मिश्रित &, && और &&, & ओवरलोड भी प्रदान करेंगे।

2

पहले टेम्पलेट मूल रूप से विफल हो जाता है, क्योंकि आप एक prvalue अस्थायी बाध्य नहीं कर सकते हैं - IntSquare() - एक गैर स्थिरांक lvalue संदर्भ के लिए।

no known conversion for argument 2 from ‘IntSquare’ to ‘Pipe<int, int>&’ 

यह कहता है कि आप प्रकार IntSquare के prvalue साथ Pipe<int, int>& प्रारंभ नहीं कर सकते हैं। दुर्भाग्य से त्रुटि श्रेणी में त्रुटि श्रेणी का स्पष्ट रूप से उल्लेख नहीं किया गया है। हालांकि यह एक मानक नियम है वीसी ++ इसे सी ++ - प्रोग्रामर दैनिक जीवन को आसान (या परेशानी) करने के लिए अनदेखा करता है। पहले किया जा रहा है int (lhs के लिए) और दूसरे जा रहा है IntSquare -

दूसरा टेम्पलेट

template <class In, class Out> 
auto operator>> (const Pipe <In, Out> &lhs, Out &rhs) -> Out& 
{ 
    rhs = lhs() ; 
    return rhs ; 
} 

Out दो अलग अलग प्रकार की वजह से के लिए दो अलग-अलग कटौती निष्कर्ष निकाला गया विफल रहता है।

+0

+1 मैंने दोनों उत्तरों को सहायक होने के लिए पाया, लेकिन मैं दूसरे के साथ गया। – jliv902

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