Parameterized Type
template < typename T >
class Vector
{
private:
T* elem;
int sz;
public:
explicit Vector(int s)
{
elem = new T[s];
sz = s;
}
T& operator[](int i)
{
if (i < 0 || i >= size()) throw out_of_range("[i] is out of bound");
return elem[i];
}
};
{
Vector< int > vi(200);
vi[0] = 123;
assert(vi[0] == 123);
}
{
Vector< string > vs(17);
vs[3] = "Hello";
assert(vs[3] == "Hello");
}
{
Vector< vector < int > > vli(45);
vli[4] = vector({ 1, 2, 3 });
assert(vli[4][1] == 2);
}
Function Template
template< typename T >
class Vector {
// ...
T* begin() const { return size() ? elem : nullptr; }
T* end() const { return begin() + size(); }
};
template< typename Container, typename Value >
Value sum(const Container& c, Value v)
{
for (auto x : c) v += x;
return v;
}
{
Vector< int > vi(4);
vi[0] = 0; vi[1] = 1; vi[2] = 2; vi[3] = 3;
double ds = sum(vi, 0.0); // summation to double
assert(ds == 6.0);
int is = sum(vi, 0); // summation to int
assert(is == 6);
}
{
list< double > ld;
ld.push_back(3.0); ld.push_back(4.0);
double ds = sum(ld, 0.0);
assert(ds == 7.0);
}
Function Object
class Shape
{
public:
virtual void draw() = 0;
virtual void rotate( double degree ) = 0;
};
class Rect : public Shape
{
public:
void draw() { cout << "rect"; }
void rotate(double degree) { cout << "rotate"; }
};
class Circle : public Shape
{
public:
void draw() { cout << "circle"; }
void rotate(double degree) {}
};
template< typename C, typename Oper >
void for_all(C& c, Oper op)
{
for (auto& x : c) op(x);
}
vector< unique_ptr< Shape > > v;
v.push_back(make_unique< Rect >());
v.push_back(make_unique< Circle >());
for_all(v, [](unique_ptr< Shape >& s){ s->draw(); });
for_all(v, [](unique_ptr< Shape >& s){ s->rotate(45); });
Variadic Templates
void foo() { cout << endl; }
template< typename T >
void bar(T x) { cout << x << " "; }
template < typename T, typename ...Tail >
void foo(T head, Tail... tail)
{
bar(head);
foo(tail...);
}
foo(1, 2, 2, "Hello");
foo(0.2, 'c', "World!", 0, 1, 2);
Function Specialization
template < class T>
T MyMax(T a, T b)
{
return a > b ? a : b;
}
template < >
const char* MyMax(const char* a, const char* b)
{
return strlen(a) > strlen(b) ? a : b;
}
assert(MyMax(1, 2) == 2);
assert(MyMax("Morning", "Afternoon") == "Afternoon");
Function Specialization - Example
struct IO {
int addr;
bool state;
};
struct Servo {
int axis;
double position;
};
struct Verify {
template< typename T >
static void Equal( T arg ) { throw exception("Should specialize"); }
static void Equal(IO io) {
cout << "check addr " << io.addr << " to be " << io.state << endl;
}
static void Equal(Servo s) {
cout << "check axis " << s.axis << " position is at " << s.position << endl;
}
};
Verify::Equal(IO{ 41, true });
Verify::Equal(Servo{ 3, 3.141592 });
Template Class Specialization - CompileTimeAssert
template< bool > struct CompileTimeAssert;
template< > struct CompileTimeAssert< true > {};
// CompileTimeAssert< sizeof(uint32_t) == 2 >();
CompileTimeAssert< sizeof(uint32_t) == 4 >();
// CompileTimeAssert< std::is_base_of::value >();
CompileTimeAssert< std::is_base_of::value >();
static_assert(std::is_base_of< Shape, Rect >::value, “Rect is a Shape");
Template Class Specialization - TypeTrait
template< typename T >
struct IsVoid {
static const bool value = false;
};
template< >
struct IsVoid< void >{
static const bool value = true;
};
template< typename T >
struct IsPointer{
static const bool value = false;
};
template< typename T >
struct IsPointer< T* >{
static const bool value = true;
};
CompileTimeAssert< IsVoid< void >::value >();
// CompileTimeAssert< IsVoid< int >::value >();
CompileTimeAssert< IsPointer< Shape* >::value >();
// CompileTimeAssert< IsPointer< Shape >::value >();
static_assert( is_pointer< Shape* >::value, "Shape* should be a pointer");
smart pointer to release resource automatically
class FILEReleasePolicy
{
public:
static void release(FILE* fp) { fclose(fp); }
};
using FILEPtr = Poco::SharedPtr;
{
FILEPtr fp = fopen("temp.txt", "wt");
fprintf(fp, "hello world");
}
No comments:
Post a Comment