C++: 模板参数的自动推导

2018-11-19  本文已影响9人  赵伯舟

简单例子

template <typename T>
T Add(T t1, T t2)
{
    return t1 + t2;
}

int main()
{
    std::cout << Add(0, 1) << std::endl;                    //works
    std::cout << Add(0.1, 1.0) << std::endl;                //works
    std::cout << Add("Hello", " World") << std::endl;       //error
    std::cout << Add(0.1, 3) << std::endl;                  //error
}

上述代码中,Add(0, 1)自动推导出模板T为整型,而Add(0.1, 3)报错,这是因为其推导出参数是两个类型:浮点数和整型,而函数声明中只有一个类型。而Add("Hello", " World")报错则是因为其推导出其类型为const char *,无法进行相加操作。
C++中的模板参数自动推导有以下原则:

  1. 编译器只根据函数调用时给出的实参列表来推导模板参数值,与函数参数类型无光的模板参数其值无法推导
  2. 与函数返回值相关的模板参数其值也无法推导。原因是C++存在内建的内动类型转化机制,函数返回值的类型可能发生隐式类型转换
  3. 所有可推导模板参数必须是连续位于模板参数列表尾部,中间不能有不可推导的模板参数

复杂例子

template <typename T0, typename T1, typename T2, typename T3, typename T4>
T2 func(T1 v1, T3 v2, T4 v3)
{
    T0 static t0 = T0(0);

    T2 t2 = v1 + v2 + v3;

    return t2;
};

int main()
{
    std::cout << func<double, int, int>(0, 1, 1.2) << std::endl;
}

上述func中用到多个模板参数,其中T0和函数实参无关,所以必须指定,而T2和返回值相关,所以也必须指定,又因为模板的形参和实参是通过位置来进行关联的,所以T1夹在T0T1之间,其也需要显式指定。T3T4则可以从实参列表中推导出来

上一篇下一篇

猜你喜欢

热点阅读