草稿
struct NoCaseCompare : public std::binary_function<std::string, std::string, bool>
{
static bool cmp(char c1, char c2)
{
return toupper(c1) < toupper(c2);
}
bool operator()(const std::string& s1, const std::string& s2) const
{
return lexicographical_compare(s1.begin(), s1.end(), s2.begin(), s2.end(), cmp);
}
};
typedef std::map<std::string, SipMessage::MethodType, NoCaseCompare> MethodTypeMap_t;
typedef std::map<SipMessage::MethodType, std::string> MethodStringMap_t;
1. std::map 的第三个参数?
Functor defined: any class that overloads operator()
Also called “function objects” because these objects can be called like functions – they can take arguments and return a value
Functors that return bool are called “predicates”
作为map的key必须实现“<”操作符,std::string 有默认的实现,但是是区分大小写的, 比如 “aaB”, "BYE", "ABC", 默认排序结果:
“ABC”
“BYE”
"aaB"
如果要实现如下的排序结果:
“aaB”
"ABC"
“BYE”
这就要自己来定义functor了
2. NoCaseCompare 为什么要继承 std::binary_function
如果不使用std::bind1st, std::bind2nd, 那么在这里继承 std::binary_function没有“实际”的意义,只是一种typedef,那么这种typedef主要目的是增加代码的可读性:
- 明确的标示出 NoCaseCompare是一个functor
- 强制规定了NoCaseCompare在重载操作符()的时候必须接受两个参数,并且强制规定了两个参数的类型和返回类型
3. operator() 后面为什么要加const?
4. NoCaseCompare 为什么要声明为struct?
从语法上,在C++中(只讨论C++中)。class和struct做类型定义时只有两点区别:
(一)默认继承权限。如果不明确指定,来自class的继承按照private继承处理,来自struct的继承按照public继承处理;
(二)成员的默认访问权限。class的成员默认是private权限,struct默认是public权限。
除了这两点,class和struct基本就是一个东西。语法上没有任何其它区别。
那这里的申明应该仅仅只是编程风格的考虑,那么这种编程风格是什么?
5. cmp函数为什么要声明为static
lexicographical_compare 这里需要的是一个函数指针
static函数实际上就是一个普通函数,只是逻辑上属于类,并可以访问类的静态成员,函数名就是指向函数地址的指针
而普通成员函数显然不能在这里被传入的,只有类的实例才能调用类的成员函数
struct HeaderIterator : public std::iterator<std::input_iterator_tag, std::string>
{
public:
HeaderIterator() : mStr(0), mSize(0), mStart(0), mEnd(0) { }
HeaderIterator(const std::string &str) : mStr(&str), mSize(mStr->size()), mStart(0), mEnd(mStr->find(CrLf)) { }
HeaderIterator(const HeaderIterator& copy) : mStr(copy.mStr), mSize(copy.mSize), mStart(copy.mStart), mEnd(copy.mEnd) { }
HeaderIterator& operator++()
{
FindNext();
return *this;
}
HeaderIterator operator++(int)
{
HeaderIterator temp(*this);
++(*this);
return temp;
}
std::string operator*() const { return std::string(*mStr, mStart, mEnd - mStart); }
bool operator==(const HeaderIterator& rhs) const { return (rhs.mStr == mStr && rhs.mStart == mStart && rhs.mEnd == mEnd); }
bool operator!=(const HeaderIterator& rhs) const { return !(rhs == *this); }
const std::string::size_type Pos(void) const { return mStart; }
private:
void FindNext(void)
{
if (mEnd == std::string::npos || ((mSize - mEnd) <= CrLf.size()))
{
mStr = 0;
mStart = mEnd = 0;
return;
}
mStart = mEnd + CrLf.size();
mEnd = mStr->find(CrLf, mStart);
}
const std::string *mStr;
const std::string::size_type mSize;
std::string::size_type mStart;
std::string::size_type mEnd;
};
// Test IPv4 addresses
SdpMessage sdp;
sdp.sessionId = 1;
sdp.timestamp = 2;
sdp.addrType = SdpMessage::SDP_ADDR_TYPE_IPV4;
sdp.addrStr = "1.2.3.4";
sdp.transportPort = 50050;
sdp.mediaFormat = SdpMessage::SDP_MEDIA_FORMAT_PCMU;
const std::string expMsgIpv4 =
"v=0\r\n"
"o=- 1 2 IN IP4 1.2.3.4\r\n"
"s=Spirent TestCenter\r\n"
"c=IN IP4 1.2.3.4\r\n"
"t=2 0\r\n"
"m=audio 50050 RTP/AVP 0 100\r\n"
"a=rtpmap:0 PCMU/8000\r\n"
"a=rtpmap:100 telephone-event/8000\r\n"
"a=ptime:20\r\n"
"a=fmtp:100 0-15\r\n";
CPPUNIT_ASSERT(SipProtocol::BuildSdpString(sdp) == expMsgIpv4);
浙公网安备 33010602011771号