C++11 理解 (二十七) 之 用于元编程的类别属性

对于那些能自行创建或修改本身或其它程序的程序,我们称之为元编程。这种行为可以发生在编译或运行期。C++ 标准委员会已经决定引进一组由模板实现的库,程序员可利用此一库于编译期进行元编程。

底下是一个以元编程来计算指数的例子:

template<int B, int N>
struct Pow {
    // recursive call and recombination.
    enum{ value = B*Pow<B, N-1>::value };
};
 
template< int B > 
struct Pow<B, 0> { 
    // ''N == 0'' condition of termination.
    enum{ value = 1 };
};
int quartic_of_three = Pow<3, 4>::value;

许多算法能作用在不同的数据类别; C++ 模板支持泛型,这使得代码能更紧凑和有用。然而,算法经常会需要目前作用的数据类别的信息。这种信息可以通过类别属性 (type traits) 于模板实体化时将该信息萃取出来。

类别属性能识别一个对象的种类和有关一个类别 (class) (或 struct) 的特征。头文件 <type_traits> 描述了我们能识别那些特征。

底下的例子说明了模板函数‘elaborate’是如何根据给定的数据类别,从而实体化某一特定的算法 (algorithm.do_it)。

// 演算法一
template< bool B > struct Algorithm {
    template<class T1, class T2> int do_it (T1 &, T2 &)  { /*...*/ }
};
 
// 演算法二
template<> struct Algorithm<true> {
    template<class T1, class T2> int do_it (T1, T2)  { /*...*/ }
};
 
// 根據給定的型別,實體化之後的 'elaborate' 會選擇演算法一或二
template<class T1, class T2> 
int elaborate (T1 A, T2 B) 
{
    // 若 T1 為 int 且 T1 為 float,選用演算法二
    // 其它情況選用演算法一
    return Algorithm<std::is_integral<T1>::value && std::is_floating_point<T2>::value>::do_it( A, B ) ;
}

通过定义在 <type_transform> 的类别属性,自定的类别转换是可能的 (在模板中,static_cast 和 const_cast 无法适用所有情况)。

此种编程技巧能写出优美、简洁的代码; 然而除错是此种编程技巧的弱处: 编译期的错误信息让人不知所云,运行期的除错更是困难。

你可能感兴趣的:(C++11 理解 (二十七) 之 用于元编程的类别属性)