模板中右值的类型推导
Type deduction for rvalues in templates
请求帮助理解右值引用的类型推导。非模板版本失败,出现以下错误,我明白原因。
error: cannot bind non-const lvalue reference of type 'const char*&'
to an rvalue of type 'const char*'
对于 C++11,如果我将函数 void Firstfun(const Key& key)
更改为 void Firstfun(const Key&& key)
,那么它会编译,但是模板化版本可以很好地使用左值引用参数。
至于模板化版本,我认为编译器一定生成了带有右值引用的函数,所以用 __PRETTY_FUNCTION__
检查了它,但在 PRETTY_FUNCTION.[=21= 的输出中没有看到它]
我确实遇到了 讨论,其中@Anirban 提到了这些内容。
For wrapper(A());, the type parameter T would still be deduced as A,
and the parameter u would be of type A&&, called an rvalue reference
to 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();
}
非模板版本的输出
error: cannot bind non-const lvalue reference of type 'const char*&'
to an rvalue of type '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
char*]
两个片段之间的主要区别在于第一个片段采用 const char*&
,第二个片段采用 const Key&
(又名 Key const&
),其中 Key
是 const char*
.
至关重要的是,在后一种情况下,这给了你一个 const char* const&
,它(像任何其他对 const
的左值引用一样)可以绑定到一个临时的。
请记住,const char*
中的 const
是无关紧要的,因为它描述的是指针对象,而不是指针。
您不需要模板。您只需编写 using Key = const char*
.
就可以观察到这一点
请求帮助理解右值引用的类型推导。非模板版本失败,出现以下错误,我明白原因。
error: cannot bind non-const lvalue reference of type 'const char*&' to an rvalue of type 'const char*'
对于 C++11,如果我将函数 void Firstfun(const Key& key)
更改为 void Firstfun(const Key&& key)
,那么它会编译,但是模板化版本可以很好地使用左值引用参数。
至于模板化版本,我认为编译器一定生成了带有右值引用的函数,所以用 __PRETTY_FUNCTION__
检查了它,但在 PRETTY_FUNCTION.[=21= 的输出中没有看到它]
我确实遇到了
For wrapper(A());, the type parameter T would still be deduced as A, and the parameter u would be of type A&&, called an rvalue reference to 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();
}
非模板版本的输出
error: cannot bind non-const lvalue reference of type 'const char*&' to an rvalue of type '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 char*]
两个片段之间的主要区别在于第一个片段采用 const char*&
,第二个片段采用 const Key&
(又名 Key const&
),其中 Key
是 const char*
.
至关重要的是,在后一种情况下,这给了你一个 const char* const&
,它(像任何其他对 const
的左值引用一样)可以绑定到一个临时的。
请记住,const char*
中的 const
是无关紧要的,因为它描述的是指针对象,而不是指针。
您不需要模板。您只需编写 using Key = const char*
.