自己写的解答,如有错误之处,烦请在评论区指正!
1
相同点:
- 参数数量和内置运算符相同
- 优先级、结合性和内置运算符相同
不同点:
- 重载的运算符要么是类的成员,要么至少含有一个类类型的参数
- 重载的
&& 、|| 不保证短路求值
2
#pragma once
#include <iostream>
using std::istream;
using std::ostream;
using std::endl;
#include <string>
using std::string;
class Sales_data {
friend istream& operator>>(istream& is, Sales_data& item);
friend ostream& operator<<(ostream& os, const Sales_data& item);
public:
Sales_data() = default;
Sales_data(const string& s) : bookNo(s) { }
Sales_data(const string& s, unsigned n, double p) :
bookNo(s), units_sold(n), revenue(p*n) { }
Sales_data(istream& is) {
double price = 0;
is >> bookNo >> units_sold >> price;
revenue = price * units_sold;
}
Sales_data operator+(const Sales_data& rhs) {
Sales_data ret = *this;
ret.units_sold += rhs.units_sold;
ret.revenue += rhs.revenue;
return ret;
}
Sales_data& operator+=(const Sales_data& rhs) {
units_sold += rhs.units_sold;
revenue += rhs.revenue;
return *this;
}
std::string isbn() const {
return bookNo;
}
double avg_price() const {
return revenue / static_cast<double>(units_sold);
}
private:
string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
istream& operator>>(istream& is, Sales_data& item) {
double price = 0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
ostream& operator<<(ostream& os, const Sales_data& item) {
os << "isbn: " << item.isbn() << endl
<< "units sold: " << item.units_sold << endl
<< "revenue: " << item.revenue << endl
<< "average price: " << item.avg_price() << endl;
return os;
}
3
a. 重载的 string 的 ==
b. 重载的 string 的 ==
c. 重载的 vector 的 ==
d. 重载的 string 的 ==
4
% 出于对称性考虑一般不作为成员
%= 复合赋值一般是成员
++ 改变对象状态,一般是成员
-> 必须是成员
<< 如果作为输出运算符一般不是,因为按照习惯左侧参数通常是一个输出流
&& 因为重载后不保证短路求值,不建议重载。如果重载了,出于对称性考虑一般不作为成员
== 出于对称性考虑一般不作为成员
() 必须是成员
5
Book:重载输入输出、相等比较
Date:重载输入输出、相等比较、大小比较、递增递减,可能会有和 int 的加减法
Employee:重载输入输出、相等比较
6
istream& operator>>(istream& is, Sales_data& item) {
double price = 0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
7
ostream& operator<<(ostream& os, const String& s) {
for (char* p = s.begin(); p != s.end(); ++p)
putchar(*p);
return os;
}
8
略
9
istream& operator>>(istream& is, Sales_data& item) {
double price;
is >> item.bookNo >> item.units_sold >> price;
if (is)
item.revenue = price * item.units_sold;
else
item = Sales_data();
return is;
}
10
a. 正常输入所有数据
b. 能正常运行,但是会读取错误的数据,并且输入流中会有残留的数据干扰下一次读取
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
#include <string>
using std::string;
#include "Sales_data.h"
int main()
{
Sales_data s1;
cin >> s1;
cout << s1 << endl;
cin >> s1;
cout << s1 << endl;
}
运行结果:
10 24.95 0-210-99999-9
isbn: 10
units sold: 24
revenue: 22.8
average price: 0.95
10 24.95 0-210-99999-9
isbn: 0-210-99999-9
units sold: 10
revenue: 249.5
average price: 24.95
11
没有判断输入流出错的情况。会读入错误的数据。
12
略
13
不需要其他算术运算符了
14
因为一般在实现 + 的时候需要返回一个局部变量的值,而先令这个局部变量等于 lhs 的值,再 += rhs 的值,代码实现很方便。
15
略
16
StrBlob:(部分成员的实现略)
class StrBlob {
friend class StrBlobPtr;
public:
typedef vector<string>::size_type size_type;
StrBlob();
StrBlob(initializer_list<string> il);
size_type size() const { return data->size(); }
bool empty() const { return data->empty(); }
void push_back(const string& t) {
data->push_back(t);
}
void push_back(string&& t) {
data->push_back(std::move(t));
}
void pop_back();
string& front() &;
const string& front() const&;
string& back() &;
const string& back() const&;
StrBlobPtr begin();
StrBlobPtr end();
bool operator==(const StrBlob& rhs) {
return data == rhs.data;
}
bool operator!=(const StrBlob& rhs) {
return !(data == rhs.data);
}
private:
shared_ptr<vector<string>> data;
void check(size_type i, const string& msg) const;
};
StrBlobPtr:(部分成员的实现略)
class StrBlobPtr {
public:
StrBlobPtr() : curr(0) { }
StrBlobPtr(StrBlob& a, size_t sz = 0) :
wptr(a.data), curr(sz) { }
string& deref() const;
StrBlobPtr& incr();
bool equ(const StrBlobPtr& rhs) {
auto spl = this->wptr.lock();
auto spr = rhs.wptr.lock();
if (spl != spr)
return false;
else
return this->curr == rhs.curr;
}
bool neq(const StrBlobPtr& rhs) {
return !(this->equ(rhs));
}
bool operator==(const StrBlobPtr& rhs) {
shared_ptr<vector<string>> spl = wptr.lock(), spr = rhs.wptr.lock();
if (spl == spr) {
if (!spl)
return true;
else
return curr == rhs.curr;
} else {
return false;
}
}
bool operator!=(const StrBlobPtr& rhs) {
return !(*this == rhs);
}
private:
shared_ptr<vector<string>> check(size_t i, const string& msg) const;
weak_ptr<vector<string>> wptr;
size_t curr;
};
StrVec:
#pragma once
#include <iostream>
using std::cout;
using std::endl;
#include <memory>
using std::allocator;
#include <string>
using std::string;
#include <utility>
using std::pair;
#include <algorithm>
#include <initializer_list>
using std::initializer_list;
class StrVec {
public:
StrVec() :
elements(nullptr), first_free(nullptr), cap(nullptr) { }
StrVec(const initializer_list<string>& list) {
auto newdata = alloc_n_copy(list.begin(), list.end());
elements = newdata.first;
first_free = cap = newdata.second;
}
StrVec(const StrVec& s) {
auto newdata = alloc_n_copy(s.begin(), s.end());
elements = newdata.first;
first_free = cap = newdata.second;
}
StrVec(StrVec&& s) noexcept :
elements(s.elements), first_free(s.first_free), cap(s.cap) {
s.elements = s.first_free = s.cap = nullptr;
}
StrVec& operator=(const StrVec& rhs) {
auto data = alloc_n_copy(rhs.begin(), rhs.end());
free();
elements = data.first;
first_free = cap = data.second;
return *this;
}
StrVec& operator=(StrVec&& rhs) noexcept {
if (this != &rhs) {
free();
elements = rhs.elements;
first_free = rhs.first_free;
cap = rhs.cap;
rhs.elements = rhs.first_free = rhs.cap = nullptr;
}
return *this;
}
bool operator==(const StrVec& rhs) const {
if (size() == rhs.size()) {
for (auto itl = begin(), itr = rhs.begin();
itl != end(); ++itl, ++itr) {
if (*itl != *itr)
return false;
}
return true;
} else {
return false;
}
}
bool operator!=(const StrVec& rhs) const {
return !(*this == rhs);
}
~StrVec() {
free();
}
void reserve(const size_t newcapacity) {
auto newdata = alloc.allocate(newcapacity);
auto dest = newdata;
auto elem = elements;
for (size_t i = 0; i != size(); ++i)
alloc.construct(dest++, std::move(*elem++));
free();
elements = newdata;
first_free = dest;
cap = elements + newcapacity;
}
void resize(const size_t newSize) {
if (newSize <= size()) {
first_free = elements + newSize;
} else {
reserve(newSize);
while (first_free != elements + newSize) {
alloc.construct(first_free++, "");
}
}
}
void push_back(const string& s) {
chk_n_alloc();
alloc.construct(first_free++, s);
}
void push_back(string&& s) {
chk_n_alloc();
alloc.construct(first_free++, std::move(s));
}
size_t size() const {
return first_free - elements;
}
size_t capacity() const {
return cap - elements;
}
string* begin() const {
return elements;
}
string* end() const {
return first_free;
}
string& operator[] (const int index) {
return *(elements + index);
}
const string& operator[] (const int index) const {
return *(elements + index);
}
void display() const {
for (auto it = begin(); it != end(); ++it)
cout << *it << endl;
}
private:
static allocator<string> alloc;
void chk_n_alloc() {
if (size() == capacity())
reallocate();
}
pair<string*, string*> alloc_n_copy(const string* b, const string* e) {
auto data = alloc.allocate(e - b);
return { data, uninitialized_copy(b, e, data) };
}
void free() {
for_each(elements, first_free, [this](string& s) {
alloc.destroy(&s);
});
alloc.deallocate(elements, cap - elements);
}
void reallocate() {
auto newcapacity = size() ? 2 * size() : 1;
auto newdata = alloc.allocate(newcapacity);
auto dest = newdata;
auto elem = elements;
for (size_t i = 0; i != size(); ++i)
alloc.construct(dest++, std::move(*elem++));
free();
elements = newdata;
first_free = dest;
cap = elements + newcapacity;
}
string* elements;
string* first_free;
string* cap;
};
allocator<string> StrVec::alloc;
String:
#pragma once
#include <iostream>
using std::ostream;
using std::cout;
using std::endl;
#include <memory>
using std::allocator;
using std::uninitialized_copy;
#include <utility>
using std::pair;
#include <algorithm>
#include <initializer_list>
using std::initializer_list;
#include <cstring>
class String {
friend ostream& operator<<(ostream& os, const String& s);
public:
String() :
elements(nullptr), first_free(nullptr), cap(nullptr) { }
String(const char* str) {
if (!str || !*str)
return;
const char* p = str;
first_free = elements = alloc.allocate(strlen(str));
while (*p) {
alloc.construct(first_free++, *p++);
}
cap = first_free;
}
String(const String& str) {
cout << "Copy construct" << endl;
auto newdata = alloc_n_copy(str.elements, str.first_free);
elements = newdata.first;
first_free = cap = newdata.second;
}
String(String&& str) noexcept :
elements(str.elements), first_free(str.first_free), cap(str.cap) {
cout << "Move construct" << endl;
str.elements = str.first_free = str.cap = nullptr;
}
String& operator=(const String& rhs) {
cout << "Copy assignment" << endl;
auto data = alloc_n_copy(rhs.elements, rhs.first_free);
free();
elements = data.first;
first_free = cap = data.second;
return *this;
}
String& operator=(String&& rhs) {
cout << "Move assignment" << endl;
if (this != &rhs) {
free();
elements = rhs.elements;
first_free = rhs.first_free;
cap = rhs.cap;
rhs.elements = rhs.first_free = rhs.cap = nullptr;
}
return *this;
}
~String() {
free();
}
void reserve(const size_t newcapacity) {
auto newdata = alloc.allocate(newcapacity);
auto dest = newdata;
auto elem = elements;
for (size_t i = 0; i != size(); ++i)
alloc.construct(dest++, std::move(*elem++));
free();
elements = newdata;
first_free = dest;
cap = elements + newcapacity;
}
void resize(const size_t newSize) {
if (newSize <= size()) {
first_free = elements + newSize;
} else {
reserve(newSize);
while (first_free != elements + newSize) {
alloc.construct(first_free++, '\0');
}
}
}
void push_back(const char ch) {
chk_n_alloc();
alloc.construct(first_free++, ch);
}
size_t size() const {
return first_free - elements;
}
size_t capacity() const {
return cap - elements;
}
char* begin() const {
return elements;
}
char* end() const {
return first_free;
}
bool operator==(const String& rhs) const {
if (size() == rhs.size()) {
for (auto itl = begin(), itr = rhs.begin();
itl != end(); ++itl, ++itr) {
if (*itl != *itr)
return false;
}
return true;
} else {
return false;
}
}
bool operator!=(const String& rhs) const {
return !(*this == rhs);
}
private:
static allocator<char> alloc;
void chk_n_alloc() {
if (size() == capacity())
reallocate();
}
pair<char*, char*> alloc_n_copy(const char* b, const char* e) {
auto data = alloc.allocate(e - b);
return { data, uninitialized_copy(b, e, data) };
}
void free() {
std::for_each(elements, first_free, [this](char& c) {
alloc.destroy(&c);
});
alloc.deallocate(elements, cap - elements);
}
void reallocate() {
auto newcapacity = size() ? 2 * size() : 1;
auto newdata = alloc.allocate(newcapacity);
auto dest = newdata;
auto elem = elements;
for (size_t i = 0; i != size(); ++i)
alloc.construct(dest++, std::move(*elem++));
free();
elements = newdata;
first_free = dest;
cap = elements + newcapacity;
}
char* elements;
char* first_free;
char* cap;
};
allocator<char> String::alloc;
ostream& operator<<(ostream& os, const String& s) {
for (char* p = s.begin(); p != s.end(); ++p)
putchar(*p);
return os;
}
17
略
18
StrBlob:
bool operator<(const StrBlob& rhs) const {
return *data < *rhs.data;
}
bool operator>(const StrBlob& rhs) const {
return *data > *rhs.data;
}
bool operator<=(const StrBlob& rhs) const {
return *data <= * rhs.data;
}
bool operator>=(const StrBlob& rhs) const {
return *data >= *rhs.data;
}
StrBlobPtr:
bool operator<(const StrBlobPtr& rhs) const {
shared_ptr<vector<string>> spl = wptr.lock(), spr = rhs.wptr.lock();
if (spl == spr) {
if (!spl)
return false;
else
return curr < rhs.curr;
} else {
return false;
}
}
bool operator>(const StrBlobPtr& rhs) const {
if (*this == rhs || *this < rhs)
return false;
else
return true;
}
bool operator<=(const StrBlobPtr& rhs) const {
return *this < rhs || *this == rhs;
}
bool operator>=(const StrBlobPtr& rhs) const {
return *this > rhs || *this == rhs;
}
StrVec:
bool operator<(const StrVec& rhs) const {
auto itl = begin(), itr = rhs.begin();
for (; itl != end() && itr != rhs.end(); ++itl, ++itr) {
if (*itl > * itr)
return false;
else if (*itl < *itr)
return true;
}
if (itl == end() && itr != rhs.end())
return true;
else
return false;
}
bool operator>(const StrVec& rhs) const {
return !(*this == rhs || *this < rhs);
}
bool operator>=(const StrVec& rhs) const {
return *this > rhs || *this == rhs;
}
bool operator<=(const StrVec& rhs) const {
return *this < rhs || *this == rhs;
}
String:
bool operator<(const String& rhs) const {
auto itl = begin(), itr = rhs.begin();
for (; itl != end() && itr != rhs.end(); ++itl, ++itr) {
if (*itl > *itr)
return false;
else if (*itl < * itr)
return true;
}
if (itl == end() && itr != rhs.end())
return true;
else
return false;
}
bool operator>(const String& rhs) const {
return !(*this == rhs || *this < rhs);
}
bool operator>=(const String& rhs) const {
return *this > rhs || *this == rhs;
}
bool operator<=(const String& rhs) const {
return *this < rhs || *this == rhs;
}
19
略
20
Sales_data operator+(const Sales_data& rhs) {
Sales_data ret = *this;
ret.units_sold += rhs.units_sold;
ret.revenue += rhs.revenue;
return ret;
}
Sales_data& operator+=(const Sales_data& rhs) {
units_sold += rhs.units_sold;
revenue += rhs.revenue;
return *this;
}
21
+= 多一次拷贝操作,效率变低
Sales_data operator+(const Sales_data& rhs) {
Sales_data ret = *this;
ret.units_sold += rhs.units_sold;
ret.revenue += rhs.revenue;
return ret;
}
Sales_data& operator+=(const Sales_data& rhs) {
*this = *this + rhs;
return *this;
}
22
Sales_data& operator=(const string& s) {
bookNo = s;
return *this;
}
23
StrVec& operator=(initializer_list<string>& il) {
free();
auto newdata = alloc_n_copy(il.begin(), il.end());
elements = newdata.first;
first_free = cap = newdata.second;
return *this;
}
24
略
25
略
26
StrBlob:
string& operator[](size_t index) {
return (*data)[index];
}
const string& operator[](size_t index) const {
return (*data)[index];
}
StrBlobPtr:
string& operator[](const size_t index) {
return (*wptr.lock())[index];
}
const string& operator[](const size_t index) const {
return (*wptr.lock())[index];
}
StrVec:
string& operator[](const size_t index) {
return *(elements + index);
}
const string& operator[](const size_t index) const {
return *(elements + index);
}
String:
char operator[](const size_t index) {
return *(elements + index);
}
const char operator[](const size_t index) const {
return *(elements + index);
}
27
StrBlobPtr& operator++() {
check(curr, "increment past end of StrBlobPtr");
++curr;
return *this;
}
StrBlobPtr& operator++(int) {
StrBlobPtr ret = *this;
++*this;
return ret;
}
StrBlobPtr operator--() {
--curr;
check(curr, "decrement past begin of StrBlobPtr");
return *this;
}
StrBlobPtr operator--(int) {
StrBlobPtr ret = *this;
--*this;
return ret;
}
28
类内的友元声明略。
StrBlobPtr operator+(const StrBlobPtr& p, const int n) {
StrBlobPtr ret = p;
ret.check(ret.curr + n, "index overflow");
ret.curr += n;
return ret;
}
StrBlobPtr operator+(const int n, const StrBlobPtr& p) {
StrBlobPtr ret = p;
ret.check(ret.curr + n, "index overflow");
ret.curr += n;
return ret;
}
StrBlobPtr operator-(const StrBlobPtr& p, const int n) {
StrBlobPtr ret = p;
ret.check(ret.curr - n, "index overflow");
ret.curr -= n;
return ret;
}
StrBlobPtr operator-(const int n, const StrBlobPtr& p) {
StrBlobPtr ret = p;
ret.check(ret.curr - n, "index overflow");
ret.curr -= n;
return ret;
}
29
因为递增递减运算符需要修改自身状态
30
StrBlobPtr:
string& operator*() const {
auto p = check(curr, "dereference past end");
return (*p)[curr];
}
string* operator->() const {
return &this->operator*();
}
ConstStrBlobPtr:
class ConstStrBlobPtr {
public:
ConstStrBlobPtr() : curr(0) { }
ConstStrBlobPtr(const StrBlob& a, size_t sz = 0) :
wptr(a.data), curr(sz) { }
const string& operator*() const {
auto p = check(curr, "dereference past end");
return (*p)[curr];
}
const string* operator->() const {
return &this->operator*();
}
private:
shared_ptr<vector<string>> check(size_t i, const string& msg) const;
weak_ptr<vector<string>> wptr;
size_t curr;
};
31
因为这个类的数据成员都是内置类型或者标准库中的类,使用编译器合成的拷贝成员就可以实现正确的语义,不用自己定义。
32
class StrBlobPtrPtr {
public:
StrBlobPtrPtr() : pointer(nullptr) { }
StrBlobPtrPtr(StrBlobPtr& p) : pointer(&p) { }
StrBlobPtr* operator->() const {
return pointer;
}
private:
StrBlobPtr* pointer;
};
33
0 个或者多个
34
#include <iostream>
using namespace std;
template <class T>
class IfThenElse {
public:
T operator()(bool first, T second, T third) {
return first ? second : third;
}
};
int main()
{
IfThenElse<int> ite;
bool flag = true;
int a = 3, b = 5;
cout << ite(flag, a, b) << endl;
cout << ite(!flag, a, b) << endl;
return 0;
}
35
class PrintString {
public:
string operator()(istream& is) {
string ret;
is >> ret;
return is ? ret : string();
}
};
36
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class GetString {
public:
string operator()(istream& is) {
string ret;
is >> ret;
return is ? ret : string();
}
};
int main()
{
vector<string> inputs;
GetString gs;
string buffer;
while (true) {
buffer = gs(cin);
if (buffer != string())
inputs.push_back(buffer);
else
break;
}
for (auto& s : inputs)
cout << s << endl;
return 0;
}
37
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
template<class T>
class IsEqual {
public:
IsEqual(T t) : target(t) { }
bool operator()(const T& obj) {
return obj == target;
}
private:
T target;
};
int main()
{
vector<int> vec{1, 2, 3, 4, 5, 5, 6, 9, 6, 5, 5, 6};
IsEqual<int> ie(5);
replace_if(vec.begin(), vec.end(), ie, 10);
for (auto n : vec)
printf("%d ", n);
return 0;
}
输出结果:
1 2 3 4 10 10 6 9 6 10 10 6
38
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class checkLength {
public:
checkLength(size_t t) : target(t) { }
bool operator()(const string& s) {
return s.size() == target;
}
private:
size_t target;
};
int main()
{
vector<string> words;
string buffer;
while (cin >> buffer) {
words.push_back(buffer);
}
for (int len = 1; len <= 10; ++len) {
checkLength cl(len);
int cnt = 0;
for (const string& s : words) {
if (cl(s))
++cnt;
}
printf("length %d: %d word(s)\n", len, cnt);
}
return 0;
}
39
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class checkLengthLess {
public:
checkLengthLess(size_t t) : target(t) { }
bool operator()(const string& s) {
return s.size() < target;
}
private:
size_t target;
};
int main()
{
vector<string> words;
string buffer;
while (cin >> buffer) {
words.push_back(buffer);
}
checkLengthLess cll(10);
int cnt = 0;
for (const string& s : words) {
if (cll(s))
++cnt;
}
printf("length less than 10: %d word(s)\n", cnt);
printf("length gerater than or equal to 10: %d word(s)\n", words.size() - cnt);
return 0;
}
40
class LessStringSize {
public:
bool operator()(const string& a, const string& b) {
return a.size() < b.size();
}
};
class CheckLengthGreaterEqual {
public:
CheckLengthGreaterEqual(size_t t) : target(t) { }
bool operator()(const string& s) {
return s.size() >= target;
}
private:
size_t target;
};
class PrintString {
public:
void operator()(const string& s) {
cout << s << " ";
}
};
void biggies(vector<string>& words, vector<string>::size_type sz) {
stable_sort(words.begin(), words.end(), LessStringSize());
auto wc = find_if(words.begin(), words.end(), CheckLengthGreaterEqual(sz));
auto count = words.end() - wc;
cout << count << " " << make_plural(count, "word", "s")
<< " of length " << sz << "or longer" << endl;
for_each(wc, words.end(), PrintString());
cout << endl;
}
41
lambda 提供了函数对象的匿名简便写法。对我来说如果一个函数对象只需要使用一次,特别是在调用标准库的泛型算法的时候,使用 lambda 很方便;如果需要多次调用一个函数对象,或者需要保存复杂的状态,使用类在语义和可读性上更好一点
42
a.
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <functional>
using namespace std;
using namespace std::placeholders;
int main() {
vector<int> vec{ 500, 600, 700, 800, 1100, 1200, 1300 };
int cnt = count_if(vec.begin(), vec.end(),
bind(greater<int>(), _1, 1024));
cout << cnt << endl;
return 0;
}
b.
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <functional>
using namespace std;
using namespace std::placeholders;
int main()
{
vector<string> vec{ "pooh", "pooh", "pooh", "pooooh", "pooh", "pooh", "pooh" };
auto it = find_if_not(vec.begin(), vec.end(),
bind(equal_to<string>(), _1, "pooh"));
cout << *it << endl;
return 0;
}
c.
参考了 传送门 的写法
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <functional>
using namespace std;
using namespace std::placeholders;
int main() {
vector<int> vec{ 500, 600, 700, 800, 1100, 1200, 1300 };
transform(vec.begin(), vec.end(), vec.begin(), bind(multiplies<int>(), _1, 2));
for_each(vec.begin(), vec.end(), [](const int n) { cout << n << " "; });
cout << "\n";
return 0;
}
43
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <functional>
using namespace std;
using namespace std::placeholders;
int main() {
vector<int> vecA{ 500, 600, 700, 800, 1100, 1200, 1300 };
vector<int> vecB{ 500, 600, 700, 800, 1100, 1200, 1300, 15 };
bool flagA = none_of(vecA.begin(), vecA.end(), bind(modulus<int>(), _1, 10));
bool flagB = none_of(vecB.begin(), vecB.end(), bind(modulus<int>(), _1, 10));
cout << flagA << endl;
cout << flagB << endl;
return 0;
}
44
#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <algorithm>
#include <functional>
using namespace std;
int main() {
map<string, function<double(double, double)>> opToFuncs = {
{"+", plus<double>()},
{"-", minus<double>()},
{"*", multiplies<double>()},
{"/", divides<double>()},
};
double a, b;
string op;
while (cin >> a >> op >> b) {
printf("%g %s %g = %g\n", a, op.c_str(), b, opToFuncs[op](a, b));
}
return 0;
}
45
explicit operator string() const {
return bookNo;
}
explicit operator double() const {
return revenue;
}
46
不应该,可以写一个成员函数来获得数据成员的值。如果确实需要转换运算符,那就声明为 explicit 的,防止产生歧义,用户在需要转换的时候显式调用
47
operator const int();
operator int() const;
第一行的转换运算符含义是:可以将对象转换成 const int 类型,且转换过程中可能会改变带转换对象的内容
第二行的转换运算符含义是:可以将对象转换成 int 类型,且转换过程中不会改变带转换对象的内容
48
略
49
略
50
int ex1 = ldObj;
可能 LongDouble 到 double 到 int,也可能 LongDouble 到 float 到 int。所以这个初始化是错误的,会产生二义性
float ex2 = ldObj;
LongDouble 到 float,初始化正确
51
P219 写出了函数重载匹配的优先级:
- 精确匹配
- const 转换
- 类型提升
- 算术类型转换或指针转换
- 类类型转换
可以看到类类型转换的优先级是最低的,所以这里会调用 void calc(int);
52
ld = si + ld;
不合法,二义性错误,可以匹配内置的 operator+(int, double) 或者内置的 operator+(int, float)
ld = ld + si;
合法,匹配的是 LongDouble operator+(const SmallInt& rhs)
53
不合法,二义性错误,可以匹配内置的算术类型加法(左操作数 SmallInt 类型类型可以类类型转换成 int),也可以匹配两个 SmallInt 类型的加法(右操作数 double 类型算术类型转换成 int 再类类型转换成 SmallInt)
|