簡體   English   中英

為什么小於運算符接受不同類型的參數而std :: min不是?

[英]Why less than operator accepts different types of params while std::min not?

#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);

---

感謝chris函數重載過后的注釋模板參數推斷不會將轉換考慮在內。 一個模板參數不能匹配兩種類型

所以std::min失敗了。

為什么<會起作用?

因為內置<應用數字促銷 ,而模板參數扣除則沒有。

正如在其他答案中所解釋的那樣,原因是std::min要求參數的類型在執行演繹時是相同的,而<暗示通常的算術轉換(§5.9/ 2),這將確保類型轉換為“共同分母”。 請注意§13.6/ 12如何將內置運算符列為候選運算符:

對於每對提升的算術類型LR ,存在該形式的候選運算符函數

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

其中LR是類型LR之間通常的算術轉換的結果。


實際上, 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)...);
}

演示

這是因為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

原始類型不會重載運算符,因此應用通常的算術轉換 ,並將int轉換為long long,“<”具有有效含義。

您甚至無法為基本類型重載運算符: https//isocpp.org/wiki/faq/intrinsic-types#intrinsics-and-operator-overloading

示例顯示您的int被提升為long long

// 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

對於二元運算符(除了移位),如果提升的操作數具有不同的類型,則應用另外一組隱式轉換,稱為通常的算術轉換,目標是生成公共類型(也可通過std :: common_type類型特征訪問)

<運算符是二進制的,因此編譯器可以將參數轉換為相同的類型並進行比較。

否則min函數應返回一些東西。 編譯器如何猜測他應該返回哪種類型?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM