2015-08-11 18 views
8
#include <iostream> 

int main(){ 
    int a = 1; 
    long long b = 2; 
    std::cout<<(a<b); 
    std::cout<<std::min(a, b); 
    return 0; 
} 

> In file included from /usr/include/c++/4.8/bits/char_traits.h:39:0, 
>     from /usr/include/c++/4.8/ios:40, 
>     from /usr/include/c++/4.8/ostream:38, 
>     from /usr/include/c++/4.8/iostream:39, 
>     from sum_to.cpp:1: /usr/include/c++/4.8/bits/stl_algobase.h:239:5: note: template<class 
> _Tp, class _Compare> const _Tp& std::min(const _Tp&, const _Tp&, _Compare) 
>  min(const _Tp& __a, const _Tp& __b, _Compare __comp) 
> ^/usr/include/c++/4.8/bits/stl_algobase.h:239:5: note: template argument deduction/substitution failed: sum_to.cpp:7:29: 
> note: deduced conflicting types for parameter ‘const _Tp’ (‘int’ and 
> ‘long long int’) 
>  std::cout<<std::min(a, b); 

--- 

function overloading post खाका तर्क कटौती में chris टिप्पणी के लिए धन्यवाद खाते में रूपांतरण नहीं लेता है। एक टेम्पलेट पैरामीटर दो प्रकार से मेल नहीं खाताऑपरेटर से कम क्यों अलग-अलग प्रकार के पैरा स्वीकार करता है जबकि std :: min नहीं?

तो std::min विफल।

क्यों < काम करेगा?

+3

क्योंकि यह * खाते में रूपांतरण लेता है। – molbdnilo

उत्तर

7

क्योंकि निर्मित < लागू होता है Numeric promotions, और टेम्पलेट तर्क कटौती नहीं करता है।

+1

क्या आप कृपया '<' के लिए विशिष्ट संदर्भ दे सकते हैं? मैं 'प्रचार' को समझ गया लेकिन पता नहीं लगा कि '' 'इस 'प्रचार' के लिए उपयुक्त क्यों है। – Kamel

+1

@ कमल यह सभी अंतर्निहित अंकगणितीय ऑपरेटरों ([लिंक] (http://en.cppreference.com/w/cpp/language/operator_arithmetic#Conversions) के लिए मामला है)। – Quentin

+0

मैंने अपने एसडीके का उपयोग करने के तरीके को जानने के लिए जावा के दस्तावेज़ को पढ़ा, सी ++ के दस्तावेज़ को पढ़ने के दौरान यह जानने के लिए कि कैसे संकलक कोड चलाने के लिए हैक करता है। – Kamel

2

ऐसा इसलिए है क्योंकि std::min एक टेम्पलेट फ़ंक्शन है।

template <class T> const T& min (const T& a, const T& b) { 
    return !(b<a)?a:b;  // or: return !comp(b,a)?a:b; for version (2) 
} 

तो यह एक ही प्रकार के लिए तर्क की जरूरत है, लेकिन अगर आप (a<b) उपयोग करते हैं, तो a परोक्ष एक long long

-1

आदिम प्रकार के लिए परिवर्तित ऑपरेटरों को ओवरलोड नहीं है, इसलिए सकता है सामान्य अंकगणितीय रूपांतरण लागू होते हैं और आपकी int को लंबे समय तक परिवर्तित कर दिया जाता है, और "<" का वैध अर्थ होता है।

तुम भी आदिम प्रकार के लिए ऑपरेटरों को ओवरलोड नहीं कर सकते हैं: https://isocpp.org/wiki/faq/intrinsic-types#intrinsics-and-operator-overloading

उदाहरण दिखाने के लिए कि अपने पूर्णांक के लिए लंबे

// common_type example 
#include <iostream> 
#include <type_traits> 

int main() { 

    typedef std::common_type<int, long long>::type A;   // i 
    std::cout << "A: " << std::is_same<long long,A>::value << std::endl; 

    return 0; 
} 

प्रलेखन http://en.cppreference.com/w/cpp/language/operator_arithmetic

बढ़ावा दिया जाता है के लिए बाइनरी ऑपरेटरों (शिफ्ट को छोड़कर), अगर प्रचारित ऑपरेटिंग में भिन्नता है erent प्रकार, अंतर्निहित रूपांतरण के अतिरिक्त सेट आवेदन किया, के लक्ष्य के साथ हमेशा की तरह गणित रूपांतरण के रूप में जाना जाता है आम प्रकार

+0

प्रचारित अंकगणितीय प्रकारों की प्रत्येक जोड़ी में उस जोड़ी के लिए परिभाषित ऑपरेटर हैं। 'int' पहले से ही एक प्रचारित अंकगणितीय प्रकार है। पदोन्नति 'int' से अधिक रैंक के साथ कुछ भी उत्पन्न नहीं करती है जब तक कि यह प्रकार को परिवर्तित न करे। 'int' -> 'लंबा लंबा' मान्य प्रचार नहीं है। – chris

+0

कृपया मेरे अपडेट किए गए उत्तर की जांच करें, मुझे डर है कि आपकी टिप्पणी वास्तविकता में क्या हो रहा है उसे प्रतिबिंबित नहीं करती है। "प्रचारित" सही शब्द नहीं हो सकता है, लेकिन "सामान्य अंकगणितीय रूपांतरण" लागू होते हैं। –

-1

< ऑपरेटर द्विआधारी है (std :: common_type प्रकार विशेषता के माध्यम से भी सुलभ) का उत्पादन , इसलिए संकलक तर्कों को एक ही प्रकार में परिवर्तित कर सकता है और उनकी तुलना कर सकता है।

अन्यथा min फ़ंक्शन कुछ वापस करना चाहिए। संकलक कैसे अनुमान लगा सकता है कि वह किस प्रकार वापस आना चाहिए?

3

के रूप में अन्य उत्तर में बताया गया है, कारण यह है कि std::min समान है, तो कटौती की जानी है होना करने के लिए तर्क के प्रकार की आवश्यकता है, जबकि < तात्पर्य सामान्य गणित रूपांतरण (§5.9/2), जो कि यकीन है कि कर देगा प्रकार को "आम संप्रदाय" में परिवर्तित कर दिया जाता है। ध्यान दें कि कैसे §13।6/12 सूचियों को उम्मीदवार के रूप में निर्मित ऑपरेटरों:

पदोन्नत अंकगणित प्रकार L और R के हर जोड़ी के लिए, वहाँ मौजूद फार्म के उम्मीदवार ऑपरेटर कार्यों

// […] 
LR operator<(L , R); 
// […] 

जहां LR परिणाम है प्रकार L और R के बीच सामान्य अंकगणितीय रूपांतरणों के।


वास्तव में, std::min भिन्न प्रकार से निपटने के लिए सक्षम होना चाहिए। निम्नलिखित एक और आधुनिक दृष्टिकोण है:

template <typename T> 
constexpr decltype(auto) min(T&& t) {return std::forward<T>(t);} 

template <typename T, typename U, typename... Args> 
constexpr auto min(T&& t, U&&u, Args&&... args) { 
    std::common_type_t<T, U> const& _t(std::forward<T>(t)), _u(std::forward<U>(u)); 
    return min(_t<_u? _t : _u, std::forward<Args>(args)...); 
} 

Demo

+0

't' और' u' को 'common_type_t ' (आदिम प्रकारों के लिए) रूपांतरित करने की संभावना नहीं है? खैर, यह कुछ मामलों में एक प्रतिलिपि नहीं बनाएगा जैसे आपका उपरोक्त कोड करेगा: हालांकि, इसे थोड़ा और प्रयास के साथ तय किया जा सकता है। – Yakk

+0

@Yakk मैंने कुछ और करने की कोशिश की। हालांकि, एक 'ऑपरेटर <' हो सकता है जो अलग-अलग वर्ग प्रकारों की तुलना करता है। फिर, 'ए <बी? ए: बी ''common_type' पर केवल दो प्रतियां करता है, जबकि मेरा कोई भी मामला तीन में करता है। हालांकि मैं आदिम प्रकारों के बारे में इतना परेशान नहीं हूं, क्योंकि मैं उम्मीद करता हूं कि संकलक उन लोगों के लिए अनुकूलन करें। – Columbo

+0

@Yakk Ahhh, यह सब अच्छा नहीं है। – Columbo

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