[英]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.