[英]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如何將內置運算符列為候選運算符:
對於每對提升的算術類型
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)...);
}
演示 。
這是因為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.