vs2013 c++编程需要添加哪些vs2015帮助文档档

如何用VS2013编写我的第一个C++程序_百度知道
如何用VS2013编写我的第一个C++程序
 第一步从百度搜索下载VS2013,然后看下图。  按ctrl+F5?3,你懂的!  打开VS2013并且点击左上角文件》》新建》》项目,输入法错误(要英文的输入法,添加》》新建项,然后弹出窗口如下所示  填好下边三项,请坚持。(我没用)确定,右键单击;”号带了吗.请根据局具体提示类型以及语句中画红色波浪下划线部分进行检查;这一句是为了使输出窗口停顿一下,名称。固定c++格式就不说明了。确定后如下图,位置。下一步,双击,体验你编写的一个C++程序的快感,解决方案名称,都尽量用英文字母。  选择visual c++》》C++文件(,不会就拼音?2。  鼠标放到右边划红线源文件三个字上,大多是格式,重点说一下cin.cpp).EXE后缀的文件,然后填好名称和位置,尤其是标点)  查看文件保存的文件夹,命名原则都是尽量用字母.get(),如下图所示。如果有错误,下一步。  输入如下所示程序在左侧窗口,则直接看下一步。找到,1每句后面带的“.大小写对了吗,下载并安装。安装步骤请详见其他百度经验
其他类似问题
为您推荐:
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁求指导vs2013c++开发软件教程_Java123社区微信号:java123msg |||[][]当前位置: &
& 求指导vs2013c++开发软件教程现在学c++有段时间啦,想开发个小软件。但vs不会用。 其实开发小软件不一定非要用ide 那用什么 /s/1o6LQeiI楼主可以去这里看看,一个VC2010开发上手的好教程,而不是市面现在学c++有段时间啦,想开发个小软件。但vs不会用。
其实开发小软件&不一定非要用ide
/s/1o6LQeiI&&楼主可以去这里看看,一个VC2010开发上手的好教程,而不是市面上较多的VC6顶一下(0)0%踩一下(2)100%------分隔线------上一篇: 下一篇: 栏目列表推荐内容#includeiostream int main() { bool flag= int a[50][50]...
下面有两段代码,只有红色标记部分的构造函数是不相同的。第...
将一个类的成员放在一个头文件中,函数的定义放在一个CPP实现...VS2013中的C++11新特性
-------------
新增文件夹...
新增文件夹
(多个标签用逗号分隔)
VS2013中的C++11新特性
Visual&C++ 2013&Preview&在6月发布了,C++开发者又找到一个编译器可以更好的支持ISO&C++ 11 的特性了.本文介绍了这些新的特性并附有代码实例.
你想动手尝试编译文中的这些代码话,需要去下载并安装Visual Studio 2013&Preview (话说:付费吗?),我尚未在其他编译器上测试这些代码,所以我并不知道与Gcc&或Clang的兼容性(可恶的C++).
原始字符串字面值
VC++ 2013现在支持原始字符串字面值了。注意:它并不支持统一码字符串字面值。一个原始字符串字面值允许你避免转义那些在HTML,XML和正则表达式里运用得得心应手的特殊字符。下面是一个示例用法:
auto s1 = R"(This is a "raw" string)";现在,s1是一个指向常量字符串值为“This is a "raw" string”的指针。尽管不支持嵌套双引号,这与C#支持的@string文字是类似的。那么要在一个字符串字面值中嵌入R"(...)"会怎样。这种情况下,你可以使用以下语法: auto s2 = R"QQ(Example: R"(This is my raw string)")QQ";现在,s2包含 Example: R"(This is my raw string)"。 在这个例子中,我把QQ作为界定符。这个界定符可以是任何长度不超过16的字符串。原始字符串字面值也可以包含换行: auto s3 = R"(&tr&
&td&data&/td&
&/tr&)";最后,不论他们什么时候添加统一码字符串字面值的支持,你都可以将它们连接起来并构成原始统一码字符串字面值。可变参数模板
可变参数模板是一个允许多个参数的模板。在我看来,这是个提供给库作者而不是给库使用者的特性,所以我也不是很确定它在C++程序员中会有多流行。以下我们用一个非常简单的例子来展示如何在实际开发中使用可变参数模板。
// Variadic template declaration
template&typename... Args& class T
// Specialization 1
template&typename T& class Test&T&
// Specialization 2
template&typename T1, typename T2& class Test&T1, T2&
void Foo()
data.Data = 24;
Test&int, int&
twovalues.Left = 12;
twovalues.Right = 15;
} 当使用可变参数模板时,智能感应(intellisense)能很好地配合我们的开发。可变参数模板的实现包括一个叫asizeof的函数,这个函数能返回这个模板的参数个数。
template&typename... Args& class Test
size_t GetTCount()
return sizeof...(Args);
size_t args = data.GetTCount(); //1
Test&int, int, char*& data2;
args = data2.GetTCount(); //3
Test&int, float& data3;
args = data3.GetTCount(); //2 这其实就是一个数个数的例子,但我猜他们之所以使用一个现存的函数名是因为这样子做会让C++程序员们更容易上手。
对于可变参数模板,一个常用的做法就是专攻其中一个参数,然后把其余的参数都变为可选。这个做法可以以递归的形式实现。以下是一个比较傻的例子,但它能让你明白什么时候不应该用可变参数模板,继而更好地了解这个语言特性。
template&typename... Args& class T
// Specialization for 0 arguments
template&& class Test&&
// Specialization for at least 1 argument
template&typename T1, typename... TRest& class Test&T1, TRest...&
: public Test&TRest...&
// This will return the base type
Test&TRest...&& Rest()
void Foo()
data.Data = 24;
Test&int, int&
twovalues.Data = 10;
// Rest() returns Test&int&
twovalues.Rest().Data = 11;
Test&int, int, char*&
threevalues.Data = 1;
// Rest() returns Test&int, int&
threevalues.Rest().Data = 2;
// Rest().Rest() returns Test&char*&
threevalues.Rest().Rest().Data = "test data";
} 大家请注意了,千万别把代码写成这样。这个例子仅仅是用来教学的,正确的做法我会在下一个章节中告诉大家。
Tuple的实现
我们来看一下std tuple的头文件&(由VC++团队的Stephan T. Lavavej负责维护 - 最初的代码由P.J. Plauger编写),浏览这些代码,让我的大脑几乎要宕掉了。为了更好的理解代码,我将代码进行简化,摘出其中可以访问tuple的值的最少的代码(能够支持读和写)。这有助于理解在设计模板类时,通常可变参数模板是如何通过递归展开来大幅减少代码的行数。
template&class... _Types&
// 空tuple
template&& class tuple&& {};
// 递归的tuple定义
template&class _This,
class... _Rest&
class tuple&_This, _Rest...&
: private tuple&_Rest...&
};这里的递归特化使用了继承,因此tuple的每个类型成员都确定的时候递归会终止。读取tuple值的时候,tuple_element类起到读取辅助类的作用。 // tuple_element
template&size_t _Index, class _Tuple& struct tuple_
// select first element
template&class _This, class... _Rest&
struct tuple_element&0, tuple&_This, _Rest...&&
typedef _This&
typedef tuple&_This, _Rest...& _T
// recursive tuple_element definition
template &size_t _Index, class _This, class... _Rest&
struct tuple_element&_Index, tuple&_This, _Rest...&&
: public tuple_element&_Index - 1, tuple&_Rest...& &
};这里又一次使用了递归继承,同时边界条件也特化了。注意这里的两个typedef,其中一个定义为对应值类型的引用,另一个定义为和tuple_element类型参数相同的tuple类型。因此,给定一个_Index值,在那个递归层次上我们就能得到对应tuple的类型和tuple值的类型。下面的get方法就使用了这个特性。 // get reference to _Index element of tuple
template&size_t _Index, class... _Types& inline
typename tuple_element&_Index, tuple&_Types...&&::type
get(tuple&_Types...&& _Tuple)
typedef typename tuple_element&_Index, tuple&_Types...&&::_Ttype _T
return (((_Ttype&) _Tuple)._Myfirst);
}注意返回类型,它使用上面定义的类型 typedef。同样,元组(tupleis)转换为上述定义过的类型 _TType ,然后我们访问 _Myfirst 成员 (它表示的值)。现在你可以如下所示,编写代码, tuple&int, char& t1;
get&0&(t1) = 959;
get&1&(t1) = 'A';
auto v1 = get&0&(t1);
auto v2 = get&1&(t1);
现在 , 这 不用 说 , 但 我会 说 只是 可以 肯定 的是 ------ 这 里只 是 为了 演示 。 不 要在 实际 代码 中 使用 这些 方法, 而是调用 std::tuple, 它可以完成比 这 一切多的功能 ( 这就是为什么他有800行长).
代理构造函数
代理构造函数已经在C#中用了好长时间,所以将其引入到C++中也很不错。编译器允许一个类型的构造函数(代理构造函数)在其初始化列表中包含另一个构造函数。以前编写代码形式如下:
class Error
Init(0, "Success");
Error(const char* message)
Init(-1, message);
Error(int errorCode, const char* message)
Init(errorCode, message);
void Init(int errorCode, const char* message)
};采用代理构造函数是,可以写成如下形式: class Error
Error() : Error(0, "Success")
Error(const char* message) : Error(-1, message)
Error(int errorCode, const char* message)
};相关阅读-& Herb Sutter和Jim Hyslop在十年前(2003年5月)写的一篇有趣的关于代理构造函数的文章。
函数模板中的默认模板参数
这是VC++ 2013现在支持的另一项C++ 11特性。目前为止,下面的代码仍然无法通过VC++编译。
template &typename T = int& void Foo(T t = 0) { }
// error C4519: default template arguments are only
// allowed on a class templateVisual C++ 2013 能够顺利编译这些代码,模板参数推断也能正确进行。 Foo(12L); // Foo&long&
Foo(12.1); // Foo&double&
Foo('A'); // Foo&char&
Foo(); // Foo&int&这项特性的实用性在下面的例子里尤为明显。 template &typename T& class Manager
void Process(T t) { }
template &typename T& class AltManager
void Process(T t) { }
template &typename T, typename M = Manager&T&& void Manage(T t)
m.Process(t);
Manage(25); // Manage&int, Manager&int&&
Manage&int, AltManager&int&&(25); // Manage&int, AltManager&int&&并不是所有的参数都需要默认参数。 template &typename B, typename T = int& void Bar(B b = 0, T t = 0) { }
Bar(10); // Bar&int, int&
Bar(10L); // Bar&long, int&
Bar(10L, 20L); // Bar&long, long&
Bar(); // will not compile如果带默认参数的函数模板有重载的话,类型无法推断的时候编译器将会给出错误。 template &typename T = int& void Foo(T t = 0) { }
template &typename B, typename T = int& void Foo(B b = 0, T t = 0) { }
Foo(12L); // will not compile
Foo(12.1); // will not compile
Foo('A'); // will not compile
Foo(); // Foo&int& 使用函数模板的默认模板参数时应当在这里注意。
显式转换运算符
我仍然记得2004年八月的一天,那个时候我意识到尽管我是一个还不错的C++程序员,我对explicit关键字一无所知,这令我十分局促不安。那之后我写了一篇博客文章
(需要翻墙)
简单说明一下explicit的使用。考虑一下下面的例子。
class Test1
explicit Test1(int) { }
void Foo()
Test1 t1(20);
Test1 t2 = 20; // will not compile
}尽管转换构造函数可以达到这一目的,转换运算符因为缺乏标准支持而无法完成类似的任务。坏消息是你无法确保转换构造函数和转换运算符的行为是一致的。考虑一下下面的例子。 class Test1
explicit Test1(int) { }
class Test2
Test2(int i) : x(i) { }
operator Test1() { return Test1(x); }
void Foo()
Test2 t1 = 20;
Test1 t2 = t1; // will compile
}上面的代码能通过编译。现在有了C++ 11的新特性,explicit也可以用在转换运算符上了。 class Test2
Test2(int i) : x(i) { }
explicit operator Test1() { return Test1(x); }
void Foo()
Test2 t1 = 20;
Test1 t2 = (Test1)t1; // this compiles
Test1 t3 = t1; // will not compile
}下面的这个例子里隐式应用了bool类型的转换运算符。 class Test3
operator bool() { }
void Foo()
bool b = t3;
}这段代码能通过编译。现在试一下在运算符上加上explicit关键字 class Test3
explicit operator bool() { }
void Foo()
if (t3) // this compiles!
bool b = t3; // will not compile
} 正如预期,第二个转换无法通过编译,但是第一个通过了。这是因为if里的bool转换被视为显式转换。因此在这里你要小心谨慎,仅仅添加explicit关键字无法防止意外情况下的类型转换,类型可能仍然是不安全的。
初始化列表和统一初始化
一直以来我们都可以用初始化列表初始化数组,现在对于有类型为std::initializer_list&T&(包含构造函数)的类型我们也可以这么做。标准库中的容器现在都支持这一特性。
void foo()
vector&int& vecint = { 3, 5, 19, 2 };
map&int, double& mapintdoub =
{ 4, 2.3},
{ 12, 4.1 },
{ 6, 0.7 }
}自己实现这些功能很浪费时间
void bar1(const initializer_list&int&& nums)
for (auto i : nums)
bar1({ 1, 4, 6 });用户自定义类型也可以使用这一特性
class bar2
bar2(initializer_list&int& nums) { }
class bar3
bar3(initializer_list&bar2& items) { }
bar2 b2 = { 3, 7, 88 };
bar3 b3 = { {1, 2}, { 14 }, { 11, 8 } };C++11也新增了一个相关特性:统一初始化( Uniform initialization)。这一特性将自动匹配合适的构造函数
class bar4
bar4(int, double, string) { }
class bar5
bar5(int, bar4) { }
bar4 b4 { 12, 14.3, "apples" };
bar5 b5 { 10, { 1, 2.1, "bananas" } };使用初始化列表的构造函数将被优先使用
class bar6
bar6(int, int) // (1)
bar6(initializer_list&int&) // (2)
bar6 b6 { 10, 10 }; // --& calls (2) above就是这些内容。像往常一样,欢迎反馈和批评建议。谢谢。
本文地址:
原文地址:
相关资讯  — 
相关文档  — 
发布时间1: 09:56:20
同类热门经验
39027次浏览
19561次浏览
26038次浏览
25672次浏览
39453次浏览
18628次浏览
OPEN-OPEN, all rights reserved.更多频道内容在这里查看
爱奇艺用户将能永久保存播放记录
过滤短视频
暂无长视频(电视剧、纪录片、动漫、综艺、电影)播放记录,
使用您的微博帐号登录,即刻尊享微博用户专属服务。
使用您的QQ帐号登录,即刻尊享QQ用户专属服务。
使用您的人人帐号登录,即刻尊享人人用户专属服务。
按住视频可进行拖动
把视频贴到Blog或BBS
当前浏览器仅支持手动复制代码
视频地址:
flash地址:
html代码:
通用代码:
通用代码可同时支持电脑和移动设备的分享播放
收藏成功,可进入查看所有收藏列表
方式1:用手机看
用爱奇艺APP或微信扫一扫,在手机上继续观看:
断剑网C++界面编程(VS2013版)第一讲
方式2:一键下载至手机
限爱奇艺安卓6.0以上版本
使用微信扫一扫,扫描左侧二维码,下载爱奇艺移动APP
其他安装方式:手机浏览器输入短链接http://71.am/164eL4
下载安装包到本机:&&
设备搜寻中...
请确保您要连接的设备(仅限安卓)登录了同一爱奇艺账号 且安装并开启不低于V6.0以上版本的爱奇艺客户端
连接失败!
请确保您要连接的设备(仅限安卓)登录了同一爱奇艺账号 且安装并开启不低于V6.0以上版本的爱奇艺客户端
部安卓(Android)设备,请点击进行选择
请您在手机端下载爱奇艺移动APP(仅支持安卓客户端)
使用微信扫一扫,下载爱奇艺移动APP
其他安装方式:手机浏览器输入短链接http://71.am/164eL4
下载安装包到本机:&&
爱奇艺云推送
请您在手机端登录爱奇艺移动APP(仅支持安卓客户端)
使用微信扫一扫,下载爱奇艺移动APP
180秒后更新
打开爱奇艺移动APP,点击“我的-扫一扫”,扫描左侧二维码进行登录
没有安装爱奇艺视频最新客户端?
爸爸去哪儿2游戏 立即参与
断剑网C++界面编程(VS2013版)第一讲
播放量数据:
你可能还想订阅他们:
&正在加载...
您使用浏览器不支持直接复制的功能,建议您使用Ctrl+C或右键全选进行地址复制
安装爱奇艺视频客户端,
马上开始为您下载本片
5秒后自动消失
&li data-elem="tabtitle" data-seq="{{seq}}"&
&a href="javascript:void(0);"&
&span>{{start}}-{{end}}&/span&
&li data-downloadSelect-elem="item" data-downloadSelect-selected="false" data-downloadSelect-tvid="{{tvid}}"&
&a href="javascript:void(0);"&{{pd}}&/a&
选择您要下载的《》剧集:
色情低俗内容
血腥暴力内容
广告或欺诈内容
侵犯了我的权力
还可以输入300字
您使用浏览器不支持直接复制的功能,建议您使用Ctrl+C或右键全选进行地址复制C++11 图说VS2013下的引用叠加规则和模板参数类型推导规则-爱编程
C++11 图说VS2013下的引用叠加规则和模板参数类型推导规则
背景:&&& 最近在学习C++STL,出于偶然,在C++Reference上看到了vector下的emplace_back函数,不想由此引发了一系列的&探索&,于是就有了现在这篇博文。
前言:&&&&&&右值引用无疑是C++11新特性中一颗耀眼的明珠,在此基础上实现了移动语义和完美转发,三者构成了令很多C++开发者拍案叫绝的&铁三角&(当然不是所有C++开发者)。而在这个&铁三角&中,有一个无法回避的关键细节,那就是引用叠加规则和模板参数类型推导规则。其实,关于这两个规则,可查到的资料不少,但都有一个特点&&简单(就形式而言)而难懂(就理解而言)(起码在下这么认为),而且,都没有例证,仅仅是简明扼要地交代。而本文恰恰是将这一细节展开,给出演示和证明。诚然,这不是什么开创性的工作,但在下认为也是必不可少的,因为它让人们对这一关键细节了解得更加深入和透彻,另外,从某个角度来说,也填补了空白。
&图说&是因为:有图有真相,一目了然,真真切切,不容辩驳。&VS2013下&是因为:本文所有测试和截图都来自VS2013,考虑到不同编译环境下结果可能会略有不同,所以,严谨起见,这里加了&VS2013下&。
最后,再说两点:&&& 1.本文的行文形式(也可以说是逻辑顺序):先结论,再证明,必要时加以解说。
&&& 2.本文使用了大量的截图,所以读起来可能会有一种连篇累牍之感(但实际上文章逻辑结构清晰,内容一目了然),给读者带来的阅读上的不适,敬请谅解。
参考资料:1.维基百科.右值引用&& 地址:http://zh.wikipedia.org/wiki/%E5%8F%B3%E5%80%BC%E5%BC%95%E7%94%A8(强烈建议大家看)2.聚客频道.[C++] 右值引用:移动语义与完美转发&& 作者:Dutor&& 地址:/entry/1059783.博客园.【原】C++ 11完美转发&& 作者:Hujian&& 地址:/hujian/archive//2355207.html4.IBM developerWorks.C++11 标准新特性: 右值引用与转移语义& 作者:李胜利&& 地址:/developerworks/cn/aix/library/1307_lisl_c11/
&&& 好了,书归正文。&为把问题说清楚,我们先给出以下函数:
template&typename T&
void f(T&& fpar)//formal parameter 形参
int& apar=a;//actual parameter 实参
&在此基础上,给出以下表格(设A为基本类型,比如int):
说明:&&&& 1.在前面的代码中,调用前形参fpar被声明的类型是T&&,调用时传入的实参apar的类型是int&。&&&& 2.上表中,2、3、4列对应了引用叠加规则,2、3、5列对应了模板参数类型推导规则。&&&& 3.由上表可以知道:&&&&&& 引用叠加规则的规律是:调用前fpar与apar中有一个是&,结果(即调用后fpar的实际类型)就是&;只有当fpar与apar都是&&时,结果才是&&。&&&&&& 模板参数类型推导规则的规律是:只有调用前fpar是&&,apar是&时,调用后T的实际类型才是A&,其余3种情况下都是A。(仅就上表,许多资料上不上这样,原因
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&在于红色部分不一样,见下面的说明4)&&&& 4.注意到上表中红色的A,在查阅过的资料中,那个位置是A&,但在下得到的结果却是A,后面会详细解释。&&&& 5.本文所讨论的模板参数类型推导,仅是针对上面例子中的T而言的,在C++11里,更经典的类型推导包括auto,decltype等。
&&& 下面逐一给出验证与说明:
1.验证规则1
&&&&&&&&&图1
&&&&程序中我们设断点监视变量,我们看到,ra作为int&类实参调用函数wai(因为是外层函数,这里简单命名为wai,不影响说明问题),调用后,T& w_a变成了int& w_a(即实际类型成了int&),而T w_aa成了int型,即T的类型是int型。这里,调用后形参w_a的实际类型满足引用叠加规则1(上表中的)。
&&&&关于引用叠加,有两种理解方式(以上例为例说明):
&&&&&&&&&&参数传递时,T&与int&&作用&,结果是int&,即T&+int&&-& int&。我们将其视为规定,不必解释。(上表正是以这种方式给出的)
&&&&&&&&参数传递时,将实参ra前面的int&传给T(即将T换成int&),于是,int&&&&-& int&(注意int& &的两个&&&间有空格,不是右值引用),而将int&&&&-&
&&&&int&视为规则。基于方式二,上表将变成(不考虑调用后T的类型):
其中,第1个&加数&是将T换成的内容,也就是实参前的类型,第2个&加数&是函数参数列表中T后的引用形式,&和&是函数调用后形参的实际形式。下面图说方式二中规定的正确性:
&&&&&&&&&& &&&&&&&&&&& &&&&&&&&&&& &&
&&&&&&& A& & -& A&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& A& && -& A&&&&&&&&&&&&&&&&&&&&&&&&&&&&& A&& & -& A&&&&&&&&&&&&&&&&&&&&&&&&&&&& &A&& && -& A&&
&&&&& 两种方式都可以。只不过在下觉得,方式二绕一点,并且,有一种T先变成int&(以图1所示为例),然后又变成int的莫名其妙之感。所以,在下推荐方式一。
&&& 在T的推导上,我们采用这样的方式:先由叠加原理得出函数调用后形参的类型,然后将该类型与函数参数列表中形参的类型进行对比、匹配,从而得出T的类型。
如果发现不能匹配,则再次运用叠加规则&推导&出T的类型(我们将在验证规则3时遇到这种情况)。
以图1中的情况为例:
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& T& w_a&&&&&(形参列表中的)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&int& w_a&&&&&(函数调用后形参的实际类型,由叠加规则决定)
&&& 对比知,T为int型。
2.验证规则2
&&&&&&&&图2
这似乎已经验证了规则2,但请看下图:
&&&&&&&&图3
&&& 不知是否有人会惊讶,a明明是右值引用,为什么会调用void f(int& lfa)?换句话说,a什么时候变成了左值?
&&&&现在,要告诉大家一个结论(相信许多人都知道,就当在下是重复吧):
&&&& C++标准规定,具名的右值引用被当作左值。[注 6]这一规定的意义在于,右值引用本来是用于实现移动语义,因而需要绑定一个对象的内存地址,然后具有修改这一对象内容的权限,这些操作与左值绑定完全一样。右值绑定与左值绑定的分野在于确定函数重载时的分辨。对于移动构造成员函数与移动赋值运算符成员函数,其形、实参数结合时是按照右值引用处理;而在这两个成员函数体内部,由于形参都是具名的,因而都被当作左值,这就可以用该形参来修改传入对象的内部状态。另外,右值引用作为xvalue(临终值)本来是用于移动语义中一次性搬空其内容。具名使其具有更为持久的生存期,这是危险的,因而规定具名后为左值引用,除非程序显式指定其类型强制转换为右值引用。&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&维基百科&& 地址:http://zh.wikipedia.org/wiki/%E5%8F%B3%E5%80%BC%E5%BC%95%E7%94%A8
&&&& 另外,从上图也可以看出,&&和&的不同可以作为重载标志。
&&&& 现在,相信大家也不再惊讶。回过头来看图2,我们明白,这个验证是无效的,ra被当成左值,相当于还是在验证规则1。那么,怎么办呢?看下图:
&&&&&&&&图4
&&& 虽然结论没有变化,但这种验证方法是有效的。
&&& 读者可以在图4代码的基础上,加入图3中的两个f函数,然后在main函数中写f(rt());会得到&右值:1&这样的输出。为缩短文章篇幅,这里就不截图了,请读者自己验证。
关于图4的代码,说以下几点:
1.前面说过,具名右值引用按左值引用处理,所以,要达到实验目的,不能将具名右值引用传给函数wai(),所以我们传函数返回值这样的不具名右值引用。
2.如果我们返回局部变量或是临时对象的引用(比如在rt()函数中写int a=1;return a++;,哪怕将int a=1;放在全局,也是不行的,因为a++就是返回++前a的一份拷贝,属于临时对象),结果是不正确的(得不到输出1)。(具体原因在下暂时还不清楚,可能是后边的代码执行时将临时变量的空间覆盖(重写)了,在下反汇编单步也没找出确切的答案(在下汇编学得不怎么样),这里烦请有知道原因的大牛给出指点,在下感激不尽,先行谢过)
3.就像大家在图4中看到的那样,rt()函数中必须将全局变量a强制类型转换为int&&型再返回,否则,如果写成return&a;,编译器将产生类似&无法将右值引用绑定到左值&的报错,原因是具名右值引用a被当做左值。
4.void wai(const T& w_a)中的const不能省,原因是非常量引用(T&)不能接受右值引用。
5.void nei(const int& n_a)中的const也不能省,正如大家在图4中看到的,在wai()中执行nei(w_a);时,w_a为const int&类型。
简单说一下T的推导:
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& const T& w_a&&&(参数列表中)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&const int& w_a&&&(函数调用后w_a的实际类型)
&&&& 对比知,T为int型。
&&&& 至此,我们可以确定,表1中红色的A是正确的,A&的说法有误。
3.验证规则3
这里只说一下T的推导。如下:
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&T&& w_a&&&&&&(参数列表中w_a的类型)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&int& w_a&&&&&&(函数调用后w_a的实际类型)
显然,此时无法直接匹配。这里我们运用表2(之所以用表2,是因为表2比表1更加直观)中的第2条A& + && -& A&,推出T为int&类型。
4.验证规则4
&&& 这里首先说一点,前边我们说过,非常量左值引用不能接受右值引用,上图中,void nei(int& n_a),w_a为int&&类型,那么,rt()中的nei(w_a);是如何通过的呢?
不要忘了,虽然w_a显示为int&&类型,但它是具名右值引用,所以作为左值引用处理,自然能够通过。如果我们将void nei(int& n_a)改为void nei(int&& n_a),反而不能通过(w_a被当做int&型,int&&不能接受int&),读者可以自己试一试。
&&& 再说一下T的推导:
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&T&& w_a&&&&&&(参数列表中w_a的类型)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&int&& w_a&&&&&&(函数调用后w_a的实际类型,不考虑C++11将其视为int&)
对比,知T为int型。
至此,4个引用叠加规则和相应的模板参数类型推导都说完了,谢谢大家!
&&&&& 在下爱钻研,喜探究,实事求是;但另一方面,又着实才疏学浅,能力有限,所以只能做一些基础性的工作。但即便如此,也难免有疏漏乃至错误之处,这里,在
&&下恳请大家批评指正,不吝赐教。您的批评指正就是在下不断进步的源泉!
版权所有 爱编程 (C) Copyright 2012. . All Rights Reserved.
闽ICP备号-3
微信扫一扫关注爱编程,每天为您推送一篇经典技术文章。}

我要回帖

更多关于 vs2012帮助文档下载 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信