IF模板一般设计如下:
template <bool /* Condition */, class Then, class /* Else */ >
struct IF {
typedef Then ret;
};
template<class Then, class Else>
struct IF<false, Then, Else> {
typedef Else ret;
};
在不支持偏特化的编译器中, 一般使用下面的方式使用全特化模拟:
namespace intimate
{
struct SelectThen
{ template<class Then, class Else>
struct Result
{ typedef Then RET;
};
}; // end SelectThen
struct SelectElse
{ template<class Then, class Else>
struct Result
{ typedef Else RET;
};
}; // end SelectElse
template<bool Condition>
struct Selector
{ typedef SelectThen RET;
}; // end Selector
template<>
struct Selector<false>
{ typedef SelectElse RET;
}; // end Selector<false>
} // end namespace private
template<bool Condition, class Then, class Else>
struct IF
{ typedef intimate::Selector<Condition>::RET select;
typedef select::Result<Then,Else>::RET RET;
}; // IF
上面的实现有点冗长. 最近使用某编译器居然不支持 namespace, 为了不让几个 Selector 污染名字空间, 发现了一种比较简单的实现方案, 有一定的通用性, 可用于将模板代码移植到不支持偏特化或名字空间的情况.
template <bool Condition , class Then, class Else>
class IF {
template<bool /* Condition */ >
struct Selector {
typedef Then ret;
};
template<>
struct Selector<false> {
typedef Else ret;
};
public:
typedef Selector<Condition>::ret ret;
};
实现技术本质上没有多大变化, 区别无非是使用嵌套类的外层类的private域充当名字空间.
使用全特化模拟偏特化, 基本原理是分离出那些与特化无关的模板参数.
在这种实现里面, 用外层类向嵌套类传递与特化无关的模板参数, 而由嵌套类实现特定模板参数的全特化.
最后在public域输出特化结果.