一文详解C++11中decltype的使用

 更新时间:2023年07月02日 16:36:34   作者:fengbingchun  
这篇文章主要为大家分享了C++11中decltype关键字的使用示例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

The decltype type specifier yields the type of a specified expression. The decltype type specifier, together with the auto keyword, is useful primarily to developers who write template libraries. Use auto and decltype to declare a template function whose return type depends on the types of its template arguments. Or,use auto and decltype to declare a template function that wraps a call to another function, and then returns the return type of the wrapped function.

The compiler uses the following rules to determine the type of the expression parameter:

(1)、If the expression parameter is an identifier or a class member access, decltype(expression) is the type of the entity named by expression. If there is no such entity or the expression parameter names a set of overloaded functions,the compiler yields an error message.

(2)、If the expression parameter is a call to a function or an overloaded operator function, decltype(expression) is the return type of the function. Parentheses around an overloaded operator are ignored.

(3)、If the expression parameter is an rvalue, decltype(expression) is the type of expression. If the expression parameter is an lvalue, decltype(expression) is an lvalue reference to the type of expression.

decltype is useful when declaring types that are difficult or impossible to declare using standard notation, like lambda-related types or types that depend on template parameters.

decltype is a standard C++11 feature. It is an "operator" which takes an expression and returns a type.

decltype与auto关键字一样,用于进行编译时类型推导,不过它与auto是有一些区别的。decltype的类型推导并不是像auto一样是从变量声明的初始化表达式获得变量的类型,而是总是以一个普通表达式作为参数,返回该表达式的类型,而且decltype并不会对表达式进行求值。

decltype关键字用于查询表达式的类型,并不会对表达式进行求值。decltype的作用是获得一个变量或表达式的类型。decltype 不会执行表达式而auto会,decltype仅仅推论一下表达式的类型。

对于decltype( e )而言,其判别结果受以下条件的影响:

(1)、如果e是一个标识符或者类成员的访问表达式,则decltype(e)就是e所代表的实体的类型。如果没有这种类型或者e是一个重载函数集,那么程序是错误的;

(2)、如果e是一个函数调用或者一个重载操作符调用(忽略e外面的括号),那么decltype(e)就是该函数的返回类型;

(3)、如果e不属于以上所述的情况,则假设e的类型是 T:当e是一个左值时,decltype(e)就是T&;否则(e是一个右值),decltype(e)是T。

auto是为所有人准备的,而decltype是提供给模板开发者的。

在C++中,decltype作为操作符,用于查询表达式的数据类型。decltype在C++11标准制定时引入,主要是为泛型编程而设计,以解决泛型编程中,由于有些类型由模板参数决定,而难以表示的问题。

下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的reference:

#include "decltype.hpp"
#include <iostream>
#include <string>
#include <utility>
#include <iomanip>
//
// reference: http://en.cppreference.com/w/cpp/language/decltype
struct A { double x; };
const A* a = new A{ 0 };
decltype(a->x) y;       // type of y is double (declared type)
decltype((a->x)) z = y; // type of z is const double& (lvalue expression)
template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u); // return type depends on template parameters
int test_decltype1()
{
	int i = 33;
	decltype(i) j = i * 2;
	std::cout << "i = " << i << ", " << "j = " << j << '\n';
	auto f = [](int a, int b) -> int
	{
		return a * b;
	};
	decltype(f) g = f; // the type of a lambda function is unique and unnamed
	i = f(2, 2);
	j = g(3, 3);
	std::cout << "i = " << i << ", " << "j = " << j << '\n';
	return 0;
}
///
// reference: https://msdn.microsoft.com/zh-cn/library/dd537655.aspx
template<typename T1, typename T2>
auto Plus(T1&& t1, T2&& t2) ->
decltype(std::forward<T1>(t1) +std::forward<T2>(t2))
{
	return std::forward<T1>(t1) +std::forward<T2>(t2);
}
class X
{
	friend X operator+(const X& x1, const X& x2)
	{
		return X(x1.m_data + x2.m_data);
	}
public:
	X(int data) : m_data(data) {}
	int Dump() const { return m_data; }
private:
	int m_data;
};
int test_decltype2()
{
	// Integer 
	int i = 4;
	std::cout << "Plus(i, 9) = " << Plus(i, 9) << std::endl;
	// Floating point
	float dx = 4.0;
	float dy = 9.5;
	std::cout << std::setprecision(3) << "Plus(dx, dy) = " << Plus(dx, dy) << std::endl;
	// String
	std::string hello = "Hello, ";
	std::string world = "world!";
	std::cout << Plus(hello, world) << std::endl;
	// Custom type
	X x1(20);
	X x2(22);
	X x3 = Plus(x1, x2);
	std::cout << "x3.Dump() = " << x3.Dump() << std::endl;
	return 0;
}
///
// reference: http://thbecker.net/articles/auto_and_decltype/section_06.html
struct S {
	S(){ m_x = 42; }
	int m_x;
};
int x;
const int cx = 42;
const int& crx = x;
const S* p = new S();
// x is declared as an int: x_type is int.
typedef decltype(x) x_type;
// auto also deduces the type as int: a_ is an int.
auto a_ = x;
// cx is declared as const int: cx_type is const int.
typedef decltype(cx) cx_type;
// auto drops the const qualifier: b is int.
auto b = cx;
// crx is declared as const int&: crx_type is const int&.
typedef decltype(crx) crx_type;
// auto drops the reference and the const qualifier: c is an int.
auto c = crx;
// S::m_x is declared as int: m_x_type is int
// Note that p->m_x cannot be assigned to. It is effectively
// constant because p is a pointer to const. But decltype goes
// by the declared type, which is int.
typedef decltype(p->m_x) m_x_type;
// auto sees that p->m_x is const, but it drops the const
// qualifier. Therefore, d is an int.
auto d = p->m_x;

GitHub: https://github.com/fengbingchun/Messy_Test

到此这篇关于一文详解C++11中decltype的使用的文章就介绍到这了,更多相关C++11 decltype内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++浅析序列数据封装与优化实现方法

    C++浅析序列数据封装与优化实现方法

    封装是面向对象编程中的把数据和操作数据的函数绑定在一起的一个概念,这样能避免受到外界的干扰和误用,从而确保了安全,数据封装是一种把数据和操作数据的函数捆绑在一起的机制,数据抽象是一种仅向用户暴露接口而把具体的实现细节隐藏起来的机制
    2022-12-12
  • C++简明讲解缺省参数与函数重载的用法

    C++简明讲解缺省参数与函数重载的用法

    所谓缺省参数,顾名思义,就是在声明函数的某个参数的时候为之指定一个默认值,在调用该函数的时候如果采用该默认值,你就无须指定该参数。C++ 允许多个函数拥有相同的名字,只要它们的参数列表不同就可以,这就是函数的重载,借助重载,一个函数名可以有多种用途
    2022-06-06
  • 详解C++的反调试技术与绕过手法

    详解C++的反调试技术与绕过手法

    反调试技术,恶意代码会用它识别自身是否被调试,或者让调试器失效,给反病毒工程师们制造麻烦,拉长提取特征码的时间线,本章将具体总结常见的反调试基础的实现原理以及如何过掉这些反调试手段,从而让我们能够继续分析恶意代码
    2021-06-06
  • c++将vector迭代器转换为指针的实现方式

    c++将vector迭代器转换为指针的实现方式

    这篇文章主要介绍了c++将vector迭代器转换为指针的实现方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • C语言实现扫雷游戏简易版

    C语言实现扫雷游戏简易版

    这篇文章主要为大家详细介绍了C语言实现扫雷游戏简易版,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-11-11
  • C/C++实现string和int相互转换的常用方法总结

    C/C++实现string和int相互转换的常用方法总结

    在C++编程中,经常需要在字符串(string)和整型(int)之间进行转换,本文将详细介绍几种在C和C++中实现这两种类型转换的常用方法,有需要的可以参考下
    2024-01-01
  • 关于C++11的统一初始化语法示例详解

    关于C++11的统一初始化语法示例详解

    C++之前的初始化语法很乱,有四种初始化方式,而且每种之前甚至不能相互转换,但从C++11出现后就好了,所以这篇文章主要给大家介绍了关于C++11的统一初始化语法的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。
    2017-10-10
  • 基于Matlab实现俄罗斯方块游戏

    基于Matlab实现俄罗斯方块游戏

    俄罗斯方块是一个最初由阿列克谢帕吉特诺夫在苏联设计和编程的益智类视频游戏。本文将利用Matlab实现这一经典的小游戏,需要的可以参考一下
    2022-03-03
  • Qt sender()函数的具体使用

    Qt sender()函数的具体使用

    在处理信号时,Qt提供了一个特殊的函数sender(),可以返回发送信号的对象指针,以实现更灵活的代码逻辑,本文就来介绍一下Qt sender()函数的具体使用,感兴趣的可以了解一下
    2024-01-01
  • 浅谈VC++中的内联

    浅谈VC++中的内联

    在 Visual C++ 中使用内联汇编 一、内联汇编的优缺点 因为在Visual C++中使用内联汇编不需要额外的编译器和联接器,且可以处理Visual C++ 中不能处理的一些事情,而且可以使用在 C/C++中的变量,所以非常方便。
    2015-07-07

最新评论