这样可以减少代码中类型的重复书写,提高代码的可读性和可维护性。...它常用于模板编程和泛型编程中,可以根据表达式推导出类型,从而避免重复书写类型。...auto x = 42; decltype(x) y; // y 的类型为 int 函数返回类型推导: decltype 可以用于推导函数返回类型,使得函数的返回类型可以根据表达式自动推导出来。...这对于模板元编程中的类型推导非常有用,因为在模板函数或类中,类型可能是未知的。...代码可读性: 过度使用 auto 和 decltype 可能会降低代码的可读性,特别是对于初学者来说。在编写代码时,应该根据实际情况慎重选择是否使用这两个关键字。
在C++11中,decltype的主要用处在当函数模板的返回类型取决于参数类型的时候。...也许答案会有些让人惊讶,带有auto返回类型的函数使用模板类型推导规则,尽管看起来auto的类型推导规则会更符合这个语义,但是模板类型推导规则和auto类型推导规则几乎是一模一样的,唯一的不同是模板类型推导规则在面对大括号的初始化式...像我们之前讨论过的,大多数[]运算符作用在以T为元素的容器上时返回一个T&,但是条款1解释了在模板类型推导期间,初始化表达式的引用部分将被忽略掉,考虑下面的客户代码,使用了带有auto返回类型(使用模板类型推导来推导它的返回类型...这里,d[5]返回了一个int&,但是对于authAndAccess函数,auto返回类型的推导将会去掉引用部分,因此产生的返回类型是int,作为函数的返回类型,int是一个右值,而上面的代码尝试把10...decltype(auto)的使用并不局限于函数的返回类型,当你想要用decltype类型推导来推导初始化式时,你也可以很方便的使用它来声明一个变量。
当编译器遇到一个函数模板的定义时,并不会马上生成相关代码,只有当我们将函数模板实例化成一个函数定义时,编译器才会生成代码。...a : b; } 但是,使用auto来推导函数的返回值类型时,会默认去掉引用和const限定符,因此,以上方式会导致返回值发生不必要的复制。...a : b; } 第一种用法需要把返回值相关的代码逻辑重复写一遍,第二种用法更简洁。 6.模板参数可以指定默认值 可以用具体的数据类型为模板参数指定默认值。...例如:当函数经常使用int类型的参数时,指定模板参数的默认值为int。...inline或constexpr在修饰时放在模板参数列表之后,返回值类型之前。
原因和extern变量一样, 普通的模板只存在于对应文件的.o中, 如果一个模板文件被多个文件实例化就会产生多份重复代码, 没有extern的话此时重复的模板会冲突...., 所以当发生冲突的时候应该显式声明构造函数来因此冲突的函数 当派生类是虚继承了基类时, 不能使用继承构造函数 一旦使用了继承构造函数(用using Base::Base;)暴露出来, 自身的默认构造函数就和之前的隐藏规则一样...不但可以调用基类的构造函数, 也可以调用当前类的其他构造函数, 这样就能进一步减少重复代码 但要注意委派构造不能和普通的初始化列表共用, 因为目标构造(初始化列表)总是先于委派构造被调用, 这会导致目标构造的参数无效...C++11给typeinfo新加入了hash_code()这个函数可以返回类型唯一的哈希值 decltype也是编译期的类型推导, 但是其从一个表达式作为参数返回该表达式的类型 有了decltype后,...各种匿名类型也都可以被重新命名并重用了 decltype只能以表达式作为参数, 所以需要获取某个函数的返回类型时可以用虚假的参数进行传入, 注意decltype是编译期进行的, 因此不会真正运行这个函数
int x = 0;decltype(x) y = x; // y的类型是int,因为x的类型是intdecltype的一个常见用途是在模板中推导函数的返回类型。...}在这个例子中,decltype(t + u)用于推导add函数的返回类型。...它基于C++的类型系统,特别是模板参数推导规则。实际上,auto的工作方式与函数模板参数的推导方式非常相似。...总结decltype和auto都是C++11引入的用于类型推导的关键字。它们的工作方式和用途有所不同,但都可以大大简化代码。decltype主要用于查询表达式的类型,特别是在模板中推导返回类型。...而auto则主要用于自动推导变量的类型,特别是在处理复杂类型或模板类型时。理解这些关键字的工作原理有助于我们更好地利用它们来编写高效、可读性强的代码。
在《深入解析C++的auto自动类型推导》和《深入解析decltype和decltype(auto)》两篇文章中介绍了使用auto和decltype以及decltype和auto结合来自动推导类型的推导规则和用法...auto与decltype转换成真实类型,最强大的是会生成模板实例化后的代码,这些功能对于调试C++代码非常有用。...需要注意的是,这个工具我发现了一个Bug,就是上面代码中的T9类型别名,正确的类型应该是func函数的类型:int(int, int),这里显示为它的返回值的类型了。...C++的RTTI特性,C++标准库提供了typeid函数和type_info类,对变量或者类型调用typeid会返回一个type_info对象,type_info类里有一个成员函数name,这个函数返回一个...这时可以采用另外一种手段来输出变量的类型,跟上小节中的例子一样借助模板的技术,实现一个模板函数,在模板函数中利用编译器提供的宏,把这个函数的原型打印出来,函数原型中就包含了函数的参数个数及其类型,这个宏由于不是
新特性一览 语言新特性 二进制字面值 泛型的Lambda表达式 初始化Lambda的捕获列表 推断返回类型 decltype(auto) 放宽对常量表达式函数的约束 变量模板 [[deprecated...(Return type deduction) 编译器会帮你尝试推断出使用auto在C14中作为的返回类型。...伴随着Lambda你现在可使用auto减少对其返回类型的描述(不再需要使用尾置返回),这还会使得返回一个推断类型或一个右值引用成为可能 // Deduce return type as `int`. auto...但是,它在推断返回类型的时候能保持它们的引用属性和const属性,这是auto所做不到的 const int x = 0; auto x1 = x; // int decltype(auto) x2 =...new运算符 当要求指针保持基础类型时避免代码的重复 最重要的,它是异常安全(exception-safety)的。
decltype与auto关键字一样,用于进行编译时类型推导。...& creator) { auto val = creator.makeObject(); // do somthing with val } 如果这个函数模板想把加工的产品作为返回值...下面来看看decltype的基本使用。简单来说,decltype关键字用于查询表达式的类型。不过,这只是其基本用法。...如果没有这种类型或者e是一个被重载的函数,则会导致编译错误。 2.如果e是一个函数调用或者一个重载操作符调用,那么decltype(e)就是该函数的返回类型(上例中的 (1))。...//规则二:推导为函数调用的返回类型 decltype(Func_1(1)) var5 = true; //bool,这是因为函数返回的是一个纯右值,对于纯右值,
auto关键字主要有两种用途:一是在变量定义时根据初始化表达式自动推断该变量的类型,二是在声明或定义函数时作为函数返回值的占位符,此时需要与关键字decltype连用。...auto不能用来声明函数的返回值。但如果函数有一个尾随的返回类型时,auto是可以出现在函数声明中返回值位置。...,注意typedef无法定义模板别名,因为typedef只能作用于具体类型而非模板 3.decltype 随着C++模板和泛型编程的广泛使用,类型推导成为了C++必备的一个能力。...(4)泛型编程中结合auto,用于追踪函数的返回值类型,这是decltype的最大用途。decltype帮助C++模板更加泛化,程序员在编写代码时无需关心任何时段的类型选择,编译器会合理地进行推导。...如果函数返回值在编译时期可以确定,那么可以使用constexpr修饰函数返回值,使函数成为常量表达式函数。
,不能是 void;例如,当 exp 调用一个返回值类型为 void 的函数时,exp 的结果也是 void 类型,此时就会导致编译错误。...如果 exp 是函数调用,那么 decltype(exp) 的类型就和函数返回值的类型一致。...y = 0; // y 的类型为 const int&& 需要注意的是,exp 中调用函数时需要带上括号和参数,但这仅仅是形式,并不会真的去执行函数代码。...但是像上面这样使用十分不方便,因为外部其实并不知道参数之间应该如何运算,只有 add 函数才知道返回值应当如何推导。 那么,在 add 函数的定义上能不能直接通过 decltype 拿到返回值呢?...t, U u) { return t + u; } 虽然成功地使用 decltype 完成了返回值的推导,但写法过于晦涩,会大大增加 decltype 在返回值类型推导上的使用难度并降低代码的可读性
decltype简介 我们之前使用的typeid运算符来查询一个变量的类型,这种类型查询在运行时进行。...RTTI机制为每一个类型产生一个type_info类型的数据,而typeid查询返回的变量相应type_info数据,通过name成员函数返回类型的名称。...同时在C++11中typeid还提供了hash_code这个成员函数,用于返回类型的唯一哈希值。...编译时类型推导的出现正是为了泛型编程,在非泛型编程中,我们的类型都是确定的,根本不需要再进行推导。 而编译时类型推导,除了我们说过的auto关键字,还有本文的decltype。...: decltype(anon_s) as ;//定义了一个上面匿名的结构体 泛型编程中结合auto,用于追踪函数的返回值类型 这也是decltype最大的用途了。
对于有序容器,关键字类型必须定义元素比较的方法。默认情况下,标准库使用使用自定义的操作来比较两个关键字。此时必须在定义关联容器类型时就提供此操作的类型。...bool compare(const A &lhs, const A &rhs); // 关于下式,第一个 compare出现的地方需要的是函数指针类型,而 // decltype返回的是一个函数类型,...而第二个 compare // 出现的地方需要的是函数指针类型的实参,此时函数名可以自动转化为一个指针 setdecltype(compare)*> aSet(compare); 当一个函数需要返回一个...在使用作用域运算符来提取一个类型成员时,记得加上模板参数: map::value_type v3; 解引用一个关联容器迭代器时,会得到一个类型为容器的 value_type...一种方法是提供自定义类型的 hash模板版本,一种方法是重载 hash函数和==运算符。
将函数的返回值标记为auto,意味着返回值类型的推导遵循模板类型推导的原则,而非auto的推导原则 C++11中加入的_trailing return type_(尾返回类型),需要搭配decltype...b) { return a + b; }; auto用于Lambda表达式时,同样代表遵循模板类型推导的原则,例如C++11中可以将其用于匿名函数参数的推导 // 使用auto接住匿名函数,匿名函数使用...处理变量时,它与auto不同,并不会去忽略掉顶层const,原变量是啥它就是啥•当decltype处理函数时,它只是获取函数的返回值类型,并不会去调用函数•当decltype处理表达式时,假设类型为Tstd...decltype(auto) 上文中提到auto作为返回值时将采用模板类型推导的规则,正因为如此它可能会遗失一些我们需要的类型(如引用或常量性),这个时候就需要使用decltype(auto) template...int&,但是由于使用模板类型推导,返回值的类型将会是int,而在C++中对右值进行赋值是非法的,因此会编译失败。
的类型是const char[13] //而模板参数类型是 const char(&)[13] 传入的参数是函数时 void someFunc(int, double); template<typename...initlist); f({11,23,9}); //正确,参数被推导为std::initializer_list C++14允许函数的返回值使用auto来自动声明返回值类型,也允许对lambda...Understand decltype C++中decltype使用的第一个场景是声明一个函数模板,它的返回值类型依赖于参数类型,常见与std::vector, std::deque 例子1: template...return std::forward(c)[i]; //因为不知道需要返回的是什么值,因此需要使用完美转发 //当传入的参数是左值时,就返回引用,传入参数是右值时...decltype(auto) myWidget2 = cw; //类型为const Widget& decltype失效的地方: 对于返回值被()包围起来的值,会产生错误的自动推导类型,因为如果返回值本身是一个左值时
auto关键字主要有两种用途:一是在变量定义时根据初始化表达式自动推断该变量的类型,二是在声明或定义函数时作为函数返回值的占位符,此时需要与关键字decltype连用。...auto不能用来声明函数的返回值。但如果函数有一个尾随的返回类型时,auto是可以出现在函数声明中返回值位置。...这种情况下,auto并不是告诉编译器去推断返回类型,而是指引编译器去函数的末端寻找返回值类型。在下面这个例子中,函数返回值类型是operator+操作符作用在T、U类型变量上的返回值类型。...(3)泛型编程中结合auto,用于追踪函数的返回值类型,这也是decltype的最大用途。...(3)在模板特例化中,也可以用 delete 来过滤一些特定的形参类型。例如,Widget 类中声明了一个函数模板,当进行模板特化时,要求禁止参数为 void* 的函数调用。
这样的话,如果在头文件中实现了某个函数,而该函数又被多个源文件使用,那么在编译时正常,而在链接时就会报错,某些函数多次重复定义。...当然,还可以通过自定义一个数据类型或使用 tuple模板来返回多个值。 与变量初始化一样,参数初始化时,会忽略掉顶层 const。因此对下式传给它常量对象或者非常量对象都是可以的。...为了编写处理不同数量实参的函数,C++11新标准提供了两种方法:所有实参类型相同,使用 initializer_list;实参类型不同, 使用可变参数模板,然后实例化即可。...auto func(int i) -> int(*)[10]; 另外,如果已经有返回值类型的数组存在,可以使用 decltype关键字声明返回类型。...另外,作为形参表达式,整体的意义是一个类型。所以使用类型别名可以简化代码,增强可读性。
一、引言在现代 C++ 编程中,我们经常会编写一些通用的代码,这些代码需要处理不同类型的可调用对象(如函数、函数指针、成员函数指针、lambda 表达式等)。...true在上述代码中,我们定义了一个普通函数 foo,它接受一个 int 类型的参数。...当我们使用 std::is_invocable 时,编译器会尝试在编译时构造一个对可调用对象 F 的调用,参数类型为 Args...。...decltype(bar), int>(); return 0;}在这个示例中,我们定义了一个辅助模板 is_invocable_helper,它使用 std::void_t 和 decltype...::is_invocable 系列类型特征为 C++ 程序员提供了强大的编译时检查能力,使得我们可以在编写通用代码时更加安全和高效。
《C++11之美》 《C++模板,判断是否存在成员函数,实现差异化操作 》 我现在关心的是如何判断一个类中有成员变量?...static auto check(_T)->typename std::decaydecltype(_T::s)>::type; decltype(_T::s)已经获取了_T::s的类型,用std...但是对于数组类型的变量,上面的写法,在gcc下编译能通过,但运行结果错误。 大概gcc认为返回的值不能是int[2]这样的数组,只能是指针。...static auto check(_T)->cl_int[2]; // 不加`std::decay`时,返回数组,无效 static auto check(_T)->cl_int*; // 加上`std...::decay`后,返回指针,有效 需要多次使用这个模板函数判断不同的成员变量时,用宏来改进上面的代码就显得很必要 /* 宏函数定义的模板函数,检查T是否有名为's'的成员 * value 为bool
(expr) decltype表达式时,返回的类型根据表达式的结果不同而不同:expr返回左值,得到该类型的左值引用;expr返回右值,得到该类型。...(int,int) pf(1,2); 那么可以返回模板函数的函数指针吗?...1,2); 和模板函数一样,如果函数是重载的,也无法通过函数名来推断返回的函数类型,那么也无法返回函数指针,如下面的例子中声明pf为函数指针是错误的。...(add_to) *pf = add_to; pf(1,2); C++ 11 中decltype的主要作用 Decltype在C++11中的主要作用是用于申明返回值类型依赖于其参数类型的模板函数。...)语法,也就是函数返回类型将在参数列表之后进行声明(在”->”之后),优点是可以使用函数参数来声明函数返回类型(如果将返回类型放置于函数之前,这里的参数x和y还没有被声明,因此不能被使用)。
1),而expression是一个函数的调用,则var的类型与函数的返回值类型相同。...返回类型后置 C++11新增加了一种函数声明的语法:在函数名和参数后面指定返回类型。...该语法与auto 搭配使用,其使用形式如下所示: auto fun(int a, int b) -> int 该语法主要是为了解决某些模板函数返回值类型问题,例如下面这个模板函数: template<...return t + u; } 该模板函数的返回值如何确定呢?...首先很容易想到的是将decltype(t+u)设置为该模板函数的返回值,但是不行的是,此时还未声明x和y,编译器还识别不到他们,更无法使用他们,因此,C++11新增了返回值类型后置的这种语法,针对上述的模板函数
领取专属 10元无门槛券
手把手带您无忧上云