#include <iostream>
#if 0
# define CONSTEXPR constexpr
#else
# define CONSTEXPR
#endif
template <typename T> struct Foo {
typedef T Type;
static const CONSTEXPR std::size_t k_Dim = sizeof(T);
};
template <typename I, typename O> struct Bar {
static const CONSTEXPR std::size_t k_IDim = I::k_Dim;
static const CONSTEXPR std::size_t k_ODim = O::k_Dim;
};
// declare
extern template struct Bar<Foo<int>, Foo<double> >;
// ----< of .h
// define in one TU
template struct Bar<Foo<int>, Foo<double> >;
// use, in another TU
int main ()
{
typedef Bar<Foo<int>, Foo<double> > Type;
std::cout << Type::k_IDim << " -- " << Type::k_ODim << "\n";
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaWYgMAojICBkZWZpbmUgQ09OU1RFWFBSIGNvbnN0ZXhwcgojZWxzZQojICBkZWZpbmUgQ09OU1RFWFBSIAojZW5kaWYKCnRlbXBsYXRlIDx0eXBlbmFtZSBUPiBzdHJ1Y3QgRm9vIHsKICAgIHR5cGVkZWYgVCBUeXBlOwogICAgc3RhdGljIGNvbnN0IENPTlNURVhQUiBzdGQ6OnNpemVfdCBrX0RpbSA9IHNpemVvZihUKTsKfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBJLCB0eXBlbmFtZSBPPiBzdHJ1Y3QgQmFyIHsKICAgIHN0YXRpYyBjb25zdCBDT05TVEVYUFIgc3RkOjpzaXplX3Qga19JRGltID0gSTo6a19EaW07CiAgICBzdGF0aWMgY29uc3QgQ09OU1RFWFBSIHN0ZDo6c2l6ZV90IGtfT0RpbSA9IE86OmtfRGltOwp9OwoKLy8gZGVjbGFyZQpleHRlcm4gdGVtcGxhdGUgc3RydWN0IEJhcjxGb288aW50PiwgRm9vPGRvdWJsZT4gPjsKCi8vIC0tLS08IG9mIC5oCgovLyBkZWZpbmUgaW4gb25lIFRVIAp0ZW1wbGF0ZSBzdHJ1Y3QgQmFyPEZvbzxpbnQ+LCBGb288ZG91YmxlPiA+OwoKLy8gdXNlLCBpbiBhbm90aGVyIFRVCmludCBtYWluICgpCnsKICAgIHR5cGVkZWYgQmFyPEZvbzxpbnQ+LCBGb288ZG91YmxlPiA+IFR5cGU7CiAgICBzdGQ6OmNvdXQgPDwgVHlwZTo6a19JRGltIDw8ICIgLS0gIiA8PCBUeXBlOjprX09EaW0gPDwgIlxuIjsKfQo=