首页 > 编程语言 >C++11:支持函数模板的默认模板参数

C++11:支持函数模板的默认模板参数

时间:2022-12-25 19:33:28浏览次数:46  
标签:11 推导 int C++ 编译器 参数 func 模板

在 C++98/03 标准中,类模板可以有默认的模板参数,如下:

template <typename T, typename U = int, U N = 0>
struct Foo
{
    // ...
};

但是却不支持函数的默认模板参数:

template <typename T = int>  // error in C++98/03: default template arguments
void func()
{
    // ...
}

现在这一限制在 C++11 中被解除了。上面的 func 函数在 C++11 中可以直接使用,代码如下:

int main(void)
{
    func();   //T = int
    return 0;
}

此时模板参数 T 的类型就为默认值 int。从上面的例子中可以看出,当所有模板参数都有默认参数时,函数模板的调用如同一个普通函数。但对于类模板而言,哪怕所有参数都有默认参数,在使用时也必须在模板名后跟随<>来实例化。

除了上面提到的部分之外,函数模板的默认模板参数在使用规则上和其他的默认参数也有一些不同,它没有必须写在参数表最后的限制。甚至于,根据实际场景中函数模板被调用的情形,编译器还可以自行推导出部分模板参数的类型。

这意味着,当默认模板参数和编译器自行推导出模板参数类型的能力一起结合使用时,代码的书写将变得异常灵活。我们可以指定函数中的一部分模板参数采用默认参数,而另一部分使用自动推导,比如下面的例子:

template <typename R = int, typename U>
R func(U val)
{
    return val;
}
int main()
{
    func(97);               // R=int, U=int
    func<char>(97);         // R=char, U=int
    func<double, int>(97);  // R=double, U=int
    return 0;
}

C++11 标准中,我们可以像 func(97) 这样调用模板函数,因为编译器可以根据实参 97 自行推导出模板参数 U 的类型为 int,并且根据返回值 val=97 推导出 R 的类型也为 int;而 func(97) 手动指定了模板参数 R 的类型为 char(默认模板参数将无效),并通过实参 97 推导出了 U = int;最后 func<double,int>(97) 手动指定的 R 和 U 的类型值,因此无需编译器自行推导。

再次强调,当默认模板参数和自行推导的模板参数同时使用时,若无法推导出函数模板参数的类型,编译器会选择使用默认模板参数;如果模板参数即无法推导出来,又未设置其默认值,则编译器直接报错。例如:

template <typename T, typename U = double>
void func(T val1 = 0, U val2 = 0)
{
    //...
}
int main()
{
    func('c'); //T=char, U=double
    func();    //编译报错
    return 0;
}

其中,func('c') 的这种调用方式,编译器通过实参 'c' 可以推导出 T=char,但由于未传递第 2 个实参,因此模板参数 U 使用的是默认参数 double;但 func() 的调用方式是不行的,虽然 val1 设置有默认值,但编译器无法通过该默认值推导出模板参数 T 的类型。由此不难看出,编译器的自动推导能力并没有想象的那么强大。

总的来说,C++11 支持为函数模板中的参数设置默认值,在实际使用过程中,我们可以选择使用默认值,也可以尝试由编译器自行推导得到,还可以亲自指定各个模板参数的类型。

标签:11,推导,int,C++,编译器,参数,func,模板
From: https://www.cnblogs.com/crossoverpptx/p/17004437.html

相关文章

  • 浅谈 C++ 模板 & 泛化 (妈妈再也不用担心我不会用 std::sort 了)
    基础复习先上个对int类型数组的插入排序:voidinsertionSort_01(int*seq,intfirstIndex,intlastIndex){for(intj=firstIndex+1;j<=lastIndex;++j......
  • C++中头文件由来及使用细节
    在刚学习C++的时候,无法一下子习惯头文件’.h’这个东西,因为在C#中,通常函数/变量的声明和实现都是写在一起的,跨.cs文件调用其他类成员时,编译器并不会冒出’未找到该......
  • Java编程思想11
    第十六章:数组Java中已经有了容器,为什么还需要数组呢,是因为数组可以持有基本类型吗?但是在泛型出来之后,通过自动包装机制,其实通过容器也能够持有基本类型。在Jav中,数组是一种......
  • C++类模板、函数模板
    类模板的声明需要template<typename类型参数>,等于C#中的泛型类,如List<T>。template<typenameT>classComplex{public://构造函数Complex(Ta,Tb)......
  • Vscode c/c++环境
    最简单的环境,用vscode插件compilec/c++,只支持单个文件,不能调试,插件主页很短一看就懂单个文件我比较喜欢用命令行编译和运行/调试多个文件cmake/makefile mac调试-lld......
  • C++进阶(unordered_set+unordered_map模拟实现)
    unordered_setunordered_set是以无特定顺序存储唯一元素的容器,并且允许根据它们的值快速检索单个元素,是一种K模型。在unordered_set中,元素的值同时是它的key,它唯一地标......
  • C/C++ATM取存款机模拟程序
    C/C++ATM取存款机模拟程序ATM取存款机模拟程序要求:设计一个程序,当输入给定的卡号和密码(初始卡号和密码为123456)时,系统能登录ATM取款机系统,用户可以按照以下规则进......
  • C/C++特色家政服务管理系统
    C/C++特色家政服务管理系统30、特色家政服务管理系统【问题详述】家政公司针对新建住宅区推出“安心入住”清扫特色家政服务,为房主清扫新装修的住房,让房主能安心地搬入......
  • C/C++通讯录管理系统
    C/C++通讯录管理系统通讯录管理系统设计题目:通讯录管理系统设计实现功能:1.创建一个通讯录(单链表的创建)。2.显示通讯录中所有联系人的信息和按组显示具体组的联系人信息......
  • C++面向对象程序设计实训(实习)[2022-12-25]
    C++面向对象程序设计实训(实习)[2022-12-25]面向对象程序设计实训(实习)PracticalTrainingofObject-OrientedProgramming1、实习基本要求(1)学生自由组1人小组按照以下要......