```
template <int v>
```

```
struct Int2Type
```

```
{
```

```
enum { value = v };
```

```
};
```

```
template <typename T>
```

```
class NiftyContainer
```

```
{
```

```
...
```

```
};
```

```
T* pSomeObj = ...;
```

```
T* pNewObj = new T(*pSomeObj);
```

```
T* pNewObj = pSomeObj->Clone();
```

```
template <typename T, bool isPolymorphicWithClone>
```

```
class NiftyContainer
```

```
{
```

```
...
```

```
};
```

```
```

```
NiftyContainer<Widget, true> widgetBag;
```

```
NiftyContainer<double, false> numberBag;
```

```
template <typename T, bool isPolymorphic>
```

```
class NiftyContainer
```

```
{
```

```
...
```

```
void DoSomething(T* pObj)
```

```
{
```

```
if (isPolymorphic)
```

```
{
```

```
... polymorphic algorithm ...
```

```
}
```

```
else
```

```
{
```

```
... non-polymorphic algorithm ...
```

```
}
```

```
}
```

```
};
```

```
template <typename T, bool isPolymorphic>
```

```
class NiftyContainer
```

```
{
```

```
private:
```

```
void DoSomething(T* pObj, Int2Type<true>)
```

```
{
```

```
... polymorphic algorithm ...
```

```
}
```

```
void DoSomething(T* pObj, Int2Type<false>)
```

```
{
```

```
... non-polymorphic algorithm ...
```

```
}
```

```
public:
```

```
void DoSomething(T* pObj)
```

```
{
```

```
DoSomething(pObj, Int2Type<isPolymorphic>());
```

```
}
```

```
};
```

```
template <typename T>
```

```
void NiftyContainer<T, true>::DoSomething(T* pObj)
```

```
{
```

```
... polymorphic algorithm ...
```

```
}
```

```
```

```
template <typename T>
```

```
void NiftyContainer<T, false>::DoSomething(T* pObj)
```

```
{
```

```
... non-polymorphic algorithm ...
```

```
}
```

```
template <typename T>
```

```
class NiftyContainer<T, false>
```

```
{
```

```
... non-polymorphic NiftyContainer ...
```

```
};
```

```
template <>
```

```
void NiftyContainer<int, false>::DoSomething(int* pObj)
```

```
{
```

```
... non-polymorphic algorithm ...
```

```
}
```

```
template <class T, class U>
```

```
T* Create(const U& arg)
```

```
{
```

```
return new T(arg);
```

```
}
```

```
// Illegal code - don't try this at home
```

```
template <class U>
```

```
Widget* Create<Widget, U>(const U& arg)
```

```
{
```

```
return new Widget(arg, -1);
```

```
}
```

```
// An implementation of Create relying on overloading
```

```
template <class T, class U>
```

```
T* Create(const U& arg, T)
```

```
{
```

```
return new T(arg);
```

```
}
```

```
template <class U>
```

```
Widget* Create(const U& arg, Widget)
```

```
{
```

```
return new Widget(arg, -1);
```

```
}
```

```
// Use Create()
```

```
String* pStr = Create("Hello", String());
```

```
Widget* pW = Create(100, Widget());
```

```
template <class T, class U>
```

```
T* Create(const U& arg, T*)
```

```
{
```

```
return new T(arg);
```

```
}
```

```
template <class U>
```

```
Widget* Create(const U& arg, Widget*)
```

```
{
```

```
return new Widget(arg, -1);
```

```
}
```

```
// Use Create()
```

```
String* pStr = Create("Hello", (String*)0);
```

```
Widget* pW = Create(100, (Widget*)0);
```

```
template <typename T>
```

```
struct Type2Type
```

```
{
```

```
typedef T OriginalType;
```

```
};
```

```
template <class T, class U>
```

```
T* Create(const U& arg, Type2Type<T>)
```

```
{
```

```
return new T(arg);
```

```
}
```

```
template <class U>
```

```
Widget* Create(const U& arg, Type2Type<Widget>)
```

```
{
```

```
return new Widget(arg, -1);
```

```
}
```

```
// Use Create()
```

```
String* pStr = Create("Hello", Type2Type<String>());
```

```
Widget* pW = Create(100, Type2Type<Widget>());
```

```
typedef char Small;
```

```
struct Big { char dummy[2]; };
```

```
Small Test(U);
```

```
Big Test(...);
```

```
const bool convExists =
```

```
sizeof(Test(T())) == sizeof(Small);
```

```
T MakeT();
```

```
const bool convExists =
```

```
sizeof(Test(MakeT())) == sizeof(Small);
```

```
template <class T, class U>
```

```
class Conversion
```

```
{
```

```
typedef char Small;
```

```
struct Big { char dummy[2]; };
```

```
static Small Test(U);
```

```
static Big Test(...);
```

```
T MakeT();
```

```
public:
```

```
enum { exists =
```

```
sizeof(Test(MakeT())) == sizeof(Small) };
```

```
};
```

```
int main()
```

```
{
```

```
using namespace std;
```

```
cout
```

```
<< Conversion<double, int>::exists << ' '
```

```
<< Conversion<char, char*>::exists << ' '
```

```
<< Conversion<size_t, vector<int> >::exists << ' ';
```

```
}
```

```
template <class T, class U>
```

```
class Conversion
```

```
{
```

```
... as above ...
```

```
enum { exists2Way = exists &&
```

```
Conversion<U, T>::exists };
```

```
enum { sameType = false };
```

```
};
```

```
template <class T>
```

```
class Conversion<T, T>
```

```
{
```

```
public:
```

```
enum { exists = 1, exists2Way = 1, sameType = 1 };
```

```
};
```

```
#define SUPERSUBCLASS(B, D) /
```

```
(Conversion<const D*, const B*>::exists && /
```

```
!Conversion<const B*, const void*>::sameType)
```

```
#define SUPERSUBCLASS_STRICT(B, D) /
```

```
(SUPERSUBCLASS(B, D) && /
```

```
!Conversion<const B, const D>::sameType)
```

相关推荐