模板中右值的类型推导
Posted
技术标签:
【中文标题】模板中右值的类型推导【英文标题】:Type deduction for rvalues in templates 【发布时间】:2018-12-24 23:33:36 【问题描述】:请求一些帮助以了解右值引用的类型推导。非模板版本失败并出现以下错误,我理解原因。
错误:无法绑定“const char*&”类型的非常量左值引用 到 'const char*' 类型的右值
在 C++11 中,如果我将函数 void Firstfun(const Key& key)
更改为 void Firstfun(const Key&& key)
,那么它会编译,但是模板版本可以与左值引用参数一起正常工作。
至于模板化版本,我认为编译器必须生成带有右值引用的函数,因此使用__PRETTY_FUNCTION__
对其进行了检查,但在 PRETTY_FUNCTION 的输出中没有看到它。
我确实遇到过this 讨论,其中@Anirban 提到了这些内容。
对于 wrapper(A());,类型参数 T 仍将推导出为 A, 参数 u 的类型为 A&&,称为右值引用 到A。
以下是我的问题:
-
编译器如何处理模板化版本以使其接受右值?
针对非模板版本的修复
void Firstfun(const Key&& key)
,是否有效且可接受?
非模板版本
#include <iostream>
namespace somens
class Firstclass
public:
void Firstfun(const char*& key)
std::cout << __PRETTY_FUNCTION__ << '\n';
;
class Secondclass
Firstclass f_class;
char* create_buf()
char * buf = new char[10]; //buf will be freed elsewhere.
return buf;
public:
void Secondfun ()
f_class.Firstfun(create_buf());
;
int main ()
somens::Secondclass s_class;
s_class.Secondfun();
非模板版本的输出
错误:无法绑定“const char*&”类型的非常量左值引用 到 'const char*' 类型的右值
模板版
#include <iostream>
namespace somens
template<typename Key>
class Firstclass
public:
void Firstfun(const Key& key)
std::cout << __PRETTY_FUNCTION__ << '\n';
;
class Secondclass
Firstclass<const char*> f_class;
char* create_buf()
char * buf = new char[10]; //buf will be freed elsewhere.
return buf;
public:
void Secondfun ()
f_class.Firstfun(create_buf());
;
int main ()
somens::Secondclass s_class;
s_class.Secondfun();
模板化版本的输出
void somens::Firstclass::Firstfun(const Key&) [with Key = const 字符*]
【问题讨论】:
【参考方案1】:您的两个 sn-ps 之间的主要区别在于,第一个采用 const char*&
,第二个采用 const Key&
(又名 Key const&
),其中 Key
是 const char*
。
至关重要的是,在后一种情况下,它会为您提供一个 const char* const&
,它(就像对 const
的任何其他左值引用一样)可以绑定到一个临时对象。
请记住,const char*
中的 const
是无关紧要的,因为它描述的是指针,而不是指针。
您不需要模板。您只需写 using Key = const char*
就可以观察到这一点。
【讨论】:
感谢您指出 const 关键字的正确位置。指针应该是 const ,因为这就是创建引用的对象。我对错误的理解是不正确的。这里取2个,请纠正或确认我的理解。它失败的原因是因为b
从char *
到char const*
的隐式转换导致了一个右值,这会在分配给函数参数时导致错误。
@user2914100 甚至没有发现。这是真的,但没关系,因为create_buf()
无论如何都是右值
你说得对,我在上一条评论中没有定义b
。假设char * b = create_buf(); f_class.Firstfun(b);
这将失败,因为从char *
到char const *
的隐式转换,我猜......
@user2914100 我想是的 :)以上是关于模板中右值的类型推导的主要内容,如果未能解决你的问题,请参考以下文章