简体   繁体   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);

---

Thanks to chris comment in function overloading post Template argument deduction doesn't take conversions into account. 感谢chris函数重载过后的注释模板参数推断不会将转换考虑在内。 One template parameter can't match two types 一个模板参数不能匹配两种类型

So std::min fail. 所以std::min失败了。

Why < would work? 为什么<会起作用?

因为内置<应用数字促销 ,而模板参数扣除则没有。

As explained in other answers, the reason is that std::min requires the types of the arguments to be identical if deduction is to be performed, while < implies the usual arithmetic conversions (§5.9/2), which will make sure that the types are converted to a "common denominator". 正如在其他答案中所解释的那样,原因是std::min要求参数的类型在执行演绎时是相同的,而<暗示通常的算术转换(§5.9/ 2),这将确保类型转换为“共同分母”。 Note how §13.6/12 lists up built-in operators as candidates: 请注意§13.6/ 12如何将内置运算符列为候选运算符:

For every pair of promoted arithmetic types L and R , there exist candidate operator functions of the form 对于每对提升的算术类型LR ,存在该形式的候选运算符函数

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

where LR is the result of the usual arithmetic conversions between types L and R . 其中LR是类型LR之间通常的算术转换的结果。


Actually, std::min should be able to deal with distinct types. 实际上, std::min应该能够处理不同的类型。 The following is a more modern approach: 以下是一种更现代的方法:

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 . 演示

It is because std::min is a template function. 这是因为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) } 

so it needs the arguments to have the same type, but if you use (a<b) , so a could implicitly converted to a long long 所以它需要具有相同类型的参数,但是如果你使用(a<b) ,那么a可以隐式转换为long long

Primitive types don't overload operators, so usual arithmetic conversions are applied and your int is converted to a long long, and the "<" has a valid meaning. 原始类型不会重载运算符,因此应用通常的算术转换 ,并将int转换为long long,“<”具有有效含义。

You can't even overload operators for primitive types: https://isocpp.org/wiki/faq/intrinsic-types#intrinsics-and-operator-overloading 您甚至无法为基本类型重载运算符: https//isocpp.org/wiki/faq/intrinsic-types#intrinsics-and-operator-overloading

Example to show that your int is promoted to long long 示例显示您的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;
}

Documentation http://en.cppreference.com/w/cpp/language/operator_arithmetic 文档http://en.cppreference.com/w/cpp/language/operator_arithmetic

For the binary operators (except shifts), if the promoted operands have different types, additional set of implicit conversions is applied, known as usual arithmetic conversions with the goal to produce the common type (also accessible via the std::common_type type trait) 对于二元运算符(除了移位),如果提升的操作数具有不同的类型,则应用另外一组隐式转换,称为通常的算术转换,目标是生成公共类型(也可通过std :: common_type类型特征访问)

The < operator is binary, so the compiler could convert arguments to the same type and compare them. <运算符是二进制的,因此编译器可以将参数转换为相同的类型并进行比较。

Otherwise min function should return something. 否则min函数应返回一些东西。 How could compiler guess which type should he return? 编译器如何猜测他应该返回哪种类型?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 std :: min of std :: chrono ::不同类型的持续时间 - std::min of std::chrono::duration of different types 为什么std :: string :: append()的功能不如std :: string :: operator +()? - Why is std::string::append() less powerful than std::string::operator+()? 为什么std ::比“&lt;”更好? - Why is std::less better than “<”? 运算符 [] 是否接受 C++ 中的整数以外的类型? - Does the operator [] accepts types other than ints in C++? std :: less是否必须与指针类型的相等运算符一致? - Does std::less have to be consistent with the equality operator for pointer types? 重载少于具有不同类型的运算符 - Overloading less than operater with different types 为什么Sortable概念需要完全有序的值类型,而std :: sort只需要“小于”可比性? - Why Sortable concept requires totally ordered value type, while std::sort only requires “less than” comparable? 重载 c++ 中的小于运算符以用于 std::sort - Overloading less than operator in c++ for use in std::sort 为什么C ++ std :: min_element库函数接受使用bool返回类型的函数对象而不是像C中的int的函子? - why C++ std::min_element library function accepts functor that takes function object of bool return type rather than int like in C? std的目的:在调用&lt;运算符时少(或类似函数) - Purpose of having std:less (or similar function) while it just call < operator
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM