功能模板

模板化也可以应用于具有相同效果的函数(以及更传统的结构)。

// 'T' stands for the unknown type
// Both of our arguments will be of the same type.
template<typename T>
void printSum(T add1, T add2)
{
    std::cout << (add1 + add2) << std::endl;
}

然后可以以与结构模板相同的方式使用它。

printSum<int>(4, 5);
printSum<float>(4.5f, 8.9f);

在这两种情况下,template 参数用于替换参数的类型; 结果就像普通的 C++函数一样(如果参数与模板类型不匹配,则编译器应用标准转换)。

模板函数的另一个属性(与模板类不同)是编译器可以根据传递给函数的参数推断模板参数。

printSum(4, 5);     // Both parameters are int.
                    // This allows the compiler deduce that the type
                    // T is also int.

printSum(5.0, 4);   // In this case the parameters are two different types.
                    // The compiler is unable to deduce the type of T
                    // because there are contradictions. As a result
                    // this is a compile time error.

此功能允许我们在组合模板结构和函数时简化代码。标准库中有一个共同的模式,允许我们使用辅助函数 make_X() 来制作 template structure X

// The make_X pattern looks like this.
// 1) A template structure with 1 or more template types.
template<typename T1, typename T2>
struct MyPair
{
    T1      first;
    T2      second;
};
// 2) A make function that has a parameter type for
//    each template parameter in the template structure.
template<typename T1, typename T2>
MyPair<T1, T2> make_MyPair(T1 t1, T2 t2)
{
    return MyPair<T1, T2>{t1, t2};
}

这有什么用?

auto val1 = MyPair<int, float>{5, 8.7};     // Create object explicitly defining the types
auto val2 = make_MyPair(5, 8.7);            // Create object using the types of the paramters.
                                            // In this code both val1 and val2 are the same
                                            // type.

注意:这不是为了缩短代码。这旨在使代码更健壮。它允许通过在单个位置而不是在多个位置更改代码来更改类型。