今日老友問我一個 c艹 的報錯問題,如下兩個版本,一個對,一個錯:
可以編譯通過:
#include <algorithm>
#include <iostream>
using namespace std;
struct Stu
{
int age;
bool operator<(const Stu& s)
{
return age > s.age;
}
};
int main()
{
Stu arr[2];
arr[0].age = 6;
arr[1].age = 8;
sort(arr, arr + 2); // [arr,arr+2)
for (auto& item : arr)
{
cout << item.age << ' ' ;
}
return 0;
}
如上正常使用,沒有報錯。
我們知道 sort 缺省函數為 less,如下模板類:
template<>
struct less<void>
{ // transparent functor for operator<
typedef int is_transparent;
template<class _Ty1,
class _Ty2>
constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
-> decltype(static_cast<_Ty1&&>(_Left)
< static_cast<_Ty2&&>(_Right))
{ // transparently apply operator< to operands
return (static_cast<_Ty1&&>(_Left) < static_cast<_Ty2&&>(_Right));
}
};
重點看這句話,參數類型非 const。
auto operator()(_Ty1&& _Left, _Ty2&& _Right)
然后我們再看下文報錯的情況
但是如果老友使用 set 函數:
error C2678: 二進制“<”: 沒有找到接受“const _Ty”類型的左操作數的運算符(或沒有可接受的轉換)
#include <set>
#include <algorithm>
#include <iostream>
using namespace std;
struct Stu
{
int age;
bool operator<(const Stu& s)
{
return age > s.age;
}
};
int main()
{
set<Stu> my_set;
my_set.insert(Stu{ 6 });
my_set.insert(Stu{ 8 });
for (auto& item : my_set)
{
cout << item.age << ' ' ;
}
return 0;
}
修改以下,可以編譯通過了:
bool operator<(const Stu& s) const // 添加 const
老友問我為什么?
我們可以通過觀察報錯說明來看:
有一句話:編譯 類 模板 成員函數 "bool std::less<_Kty>::operator ()(const _Ty &,const _Ty &) const" 時******
因為我們自定義了 Stu 類的排序規則,即重載了 operator<.
Set 內部排序缺省函數位 less
我們去看一下類模板 less
template<class _Ty = void>
struct less
{ // functor for operator<
constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const
{ // apply operator< to operands
return (_Left < _Right);
}
};
看到參數是 const _Ty& _Left, const _Ty& _Right,所以傳入的 this 對象引用變成 const _Ty& _Left,而 _Left 是 const 導致無法調用非 cosnt 成員函數 opertator<。所以需要添加 const 使其變成 const 成員函數
關於const的作用:
表示成員函數隱含傳入的this指針為const指針
后面加 const表示函數不可以修改class的成員
https://blog.csdn.net/SMF0504/article/details/52311207