将函数 functionality 与模板参数关联起来是有用的
因而客服端程序员在编码的时候能够轻松地定制代码行为
//: C05:BearCorner2.cpp
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
// Illustrates policy classes.
#include <iostream>
#include "BearCorner.h"
using namespace std;
// Policy classes (require a static doAction() function):
class Feed {
public:
static const char* doAction() { return "Feeding"; }
};
class Stuff {
public:
static const char* doAction() { return "Stuffing"; }
};
// The Guest template (uses a policy and a traits class)
template<class Guest, class Action,
class traits = GuestTraits<Guest> >
class BearCorner {
Guest theGuest;
typedef typename traits::beverage_type beverage_type;
typedef typename traits::snack_type snack_type;
beverage_type bev;
snack_type snack;
public:
BearCorner(const Guest& g) : theGuest(g) {}
void entertain() {
cout << Action::doAction() << " " << theGuest
<< " with " << bev
<< " and " << snack << endl;
}
};
int main() {
Boy cr;
BearCorner<Boy, Feed> pc1(cr);
pc1.entertain();
Bear pb;
BearCorner<Bear, Stuff> pc2(pb);
pc2.entertain();
getchar();
} ///:~
输出
Feeding Patrick with Milk and Cookies
Stuffing Theodore with Condensed Milk and Honey
BearCorner类中的Action模板参数希望有一个名为doAction()静态成员函数
它用在BearCorner<>::entertain()中
用户按照意愿可以选择Feed或Stuff
两者都提供了所需的函数剩下的代码
//: C05:BearCorner.h
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
#ifndef BEARCORNER_H
#define BEARCORNER_H
#include <iostream>
using std::ostream;
// Item classes (traits of guests):
class Milk {
public:
friend ostream& operator<<(ostream& os, const Milk&) {
return os << "Milk";
}
};
class CondensedMilk {
public:
friend ostream&
operator<<(ostream& os, const CondensedMilk &) {
return os << "Condensed Milk";
}
};
class Honey {
public:
friend ostream& operator<<(ostream& os, const Honey&) {
return os << "Honey";
}
};
class Cookies {
public:
friend ostream& operator<<(ostream& os, const Cookies&) {
return os << "Cookies";
}
};
// Guest classes:
class Bear {
public:
friend ostream& operator<<(ostream& os, const Bear&) {
return os << "Theodore";
}
};
class Boy {
public:
friend ostream& operator<<(ostream& os, const Boy&) {
return os << "Patrick";
}
};
// Primary traits template (empty-could hold common types)
template<class Guest> class GuestTraits;
// Traits specializations for Guest types
template<> class GuestTraits<Bear> {
public:
typedef CondensedMilk beverage_type;
typedef Honey snack_type;
};
template<> class GuestTraits<Boy> {
public:
typedef Milk beverage_type;
typedef Cookies snack_type;
};
#endif // BEARCORNER_H ///:~