2009-08-30 5 views
6

मुझे कुछ valarray फ़ंक्शन पॉइंटर कोड के साथ समस्या हो रही है:मैं std :: sin (const valarray <double> &) का संदर्भ कैसे दूं?

double (*fp)(double) = sin; 
valarray<double> (*fp)(const valarray<double> &) = sin; 

पहला संकलन, दूसरा देता है:

error: no matches converting function 'sin' to type 'class std::valarray<double> (*)(const class std::valarray<double>&)' 

उत्तर

11

यह संकलित करने के लिए अनुकूलित किया जा सकता है, __typeof__ जीसीसी एक्सटेंशन का उपयोग कर। ऐसा लगता है कि जीसीसी के valarray साइनस की गणना में देरी के लिए अभिव्यक्ति टेम्पलेट का उपयोग करता है। लेकिन इससे sin टेम्पलेट का रिटर्न प्रकार बिल्कुल valarray<T> नहीं होगा, बल्कि कुछ अजीब जटिल प्रकार होगा।

#include <valarray> 

template<typename T> struct id { typedef T type; }; 
int main() { 
    using std::valarray; 
    using std::sin; 

    id<__typeof__(sin(valarray<double>()))>::type (*fp)(const valarray<double> &) = sin; 
} 

संपादित करें: AProgrammer के देखें क्यों जीसीसी ठीक कर रही है के लिए मानक बोली।

संपादित करें: स्टैंडर्ड अनुरूप वैकल्पिक हल

एक सख्ती से मानक अनुरूप तरह से __typeof__ बिना ऐसा करने से आपको थोड़ी सूझबूझ से है। आपको रिटर्न प्रकार sin प्राप्त करने की आवश्यकता होगी। आप इसके लिए सशर्त ऑपरेटर का उपयोग कर सकते हैं, जैसे एरिक नीबलर has shown। यह sin फ़ंक्शन को वास्तव में नहीं बुलाया जाता है, लेकिन केवल टाइप-चेक किया जाता है।

#include <valarray> 

using std::valarray; 

template<typename T> struct id { 
    typedef T type; 
}; 

struct ded_ty { 
    template<typename T> 
    operator id<T>() { return id<T>(); } 
}; 

template<typename E, typename T> 
id<T(*)(valarray<E> const&)> genFTy(T t) { 
    return id<T(*)(valarray<E> const&)>(); 
} 

template<typename T> 
void work(T fp, id<T>) { 
    // T is the function pointer type, fp points 
    // to the math function. 
} 

int main() { 
    work(std::sin, 1 ? ded_ty() : genFTy<double>(std::sin(valarray<double>()))); 
} 

: दूसरी शाखा (एक जो वास्तव में मूल्यांकन किया जाता है) कि एक ही प्रकार के लिए सशर्त ऑपरेटर की परिवर्तित करने के लिए कोशिश कर करके, हम एक डमी पैरामीटर उत्पन्न कर सकते हैं बस समारोह सूचक के प्रकार के अनुमान करने में सक्षम हो अगर आप तुरंत पता प्राप्त करना चाहते हैं, तो आप work लिख सकते हैं, इसलिए यह fp फिर से लौटाता है।

template<typename T> 
T addy(T fp, id<T>) { return fp; } 

अब, तुम अंत में सशर्त ऑपरेटर प्रवंचना संपुटित करने के लिए एक मैक्रो लिखते हैं, और इसका इस्तेमाल करते हैं जब आप किसी भी तरह के गणित समारोह का पता प्राप्त करना चाहते हैं कर सकते हैं।

#define DEDUCE(FN,Y) (1 ? ded_ty() : genFTy<Y>(FN(std::valarray<Y>()))) 

पते और फिर

std::transform(v1.begin(), v1.end(), v1.begin(), 
    addy(std::sin, DEDUCE(std::sin, double))); 
std::transform(v2.begin(), v2.end(), v2.begin(), 
    addy(std::cos, DEDUCE(std::cos, double))); 
+1

मैं इस समस्या के समाधान में एक सशर्त ऑपरेटर को मोड़ने की आपकी मैकजीवर जैसी क्षमता से एक साथ प्रभावित हुआ है, और भयभीत है कि ऐसा करना आवश्यक था। :) –

+0

वाह। मुझे समझ में नहीं आ रहा है। मुझे इसका अध्ययन करना होगा ... –

+1

@robert, अगर कुछ पैसे हैं तो प्रश्न पूछने के लिए स्वतंत्र महसूस करें आरटीएस आप समझ में नहीं आता है। मैं तब उनके लिए स्पष्टीकरण देने की कोशिश करूंगा। यह भी सुनिश्चित करें कि 'ऑपरेटर' के उपयोग के एरिक निबेलर्स स्पष्टीकरण को पढ़ना सुनिश्चित करें: http://www.artima.com/cppsource/foreach2.html –

4

आप शीर्षक में std::sin के बारे में बात करते हैं, लेकिन फिर ::sin आवंटित।

valarray<double> (*fp)(const valarray<double> &) = std::sin; 

यही काम करना चाहिए। ध्यान दें, आपको sin के सभी उपयोगों को अर्हता प्राप्त करनी चाहिए, हालांकि अधिकांश कार्यान्वयन वैश्विक नामस्थान में नाम इंजेक्ट करेंगे, भले ही आप <cmath> (जो गैर मानक व्यवहार है) शामिल हों।

संपादित करें: दुर्भाग्यवश, आप भाग्य से बाहर हैं। मानक sin(valarray<T> const &) निम्नलिखित (26.3.3.3) के बारे में बताता है।

यह समारोह एक मान प्रकार टी की है या जो स्पष्ट रूप से टी टाइप करने के लिए

जीसीसी द्वारा किया जाता अनुकूलन मानक द्वारा प्रदान किया जाता है परिवर्तित किया जा सकता है जो लौटा देगा। उपरोक्त कोड काम करने की गारंटी नहीं है।

+0

यह या तो जीसीसी पर मेरे लिए काम नहीं करता है, कुछ सामान्य कार्य करने के लिए इसे पारित निम्न कार्य करने के लिए। वही त्रुटि संदेश :( –

+1

आप सही हैं, जीसीसी पर यह वास्तव में विफल रहता है। मैं कहूंगा कि यह एक बग है। मानक स्पष्ट रूप से 'टेम्पलेट वैलराय पाप (कॉन्स वैलेर्रे और) को परिभाषित करता है;' जो निश्चित रूप से परिवर्तनीय है ' valarray (*) (स्थिरांक valarray और) '। – avakar

+0

मैं सहमत हूँ। एक जीसीसी पागलपन की तरह लग रहा :( –

10

26 3,1/3

एक valarray लौटने किसी भी समारोह, एक और प्रकार का ऑब्जेक्ट वापस जाने के लिए अनुमति दी है प्रदान की गयी सभी स्थिरांक सदस्य valarray का कार्य भी इस प्रकार के लिए लागू कर रहे हैं।

उद्देश्य टेम्पलेट भाव (बजाय सीधे> की एक अस्थायी निर्माण जिसके परिणामस्वरूप valarray < को बताए अर्थात प्रत्येक बार गणना कर पूरे सरणी पर एक बार पाशन,) परिणाम अनुकूलन करने के लिए इस्तेमाल किया जा करने की अनुमति है।

z = sin(x+y); 

for (i = 0; i < N; ++i) 
    z[i] = sin(x[i] + y[i]); 
+0

+1, कि बनाता है भावना। xD –

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