shr*_*ike 7 c++ templates c++11 c++14
我有一个模板功能,func
:
template<typename T>
void func(T p) { f(p); }
Run Code Online (Sandbox Code Playgroud)
还有一套功能f
:
f(SomeType&);
f(int);
...
Run Code Online (Sandbox Code Playgroud)
如果我实例化模板函数,func
使用引用作为函数参数p
,而不显式指定模板参数T
,那么推导出的类型将不是引用类型p
,而是类型p
是对它的引用,例如:
SomeType s;
SomeType& ref_to_s = s;
func(ref_to_s); // Type deduction results in: func<SomeType>(ref_to_s)
func<SomeType&>(ref_to_s); // Need to explicitly specify type to work with reference
Run Code Online (Sandbox Code Playgroud)
所以,我的问题是:
SomeType&
在上述情况下无法推断出引用类型?func
,因此类型推导与引用类型一起使用,而没有明确指定模板参数T
?要清楚,我想要两者兼顾(参见f
上面的函数):
func(ref_to_s); // Calls func<SomeType&>(ref_to_s)
func(1); // Calls func<int>(1)
Run Code Online (Sandbox Code Playgroud)
第一部分的答案是从值初始化对象并将引用绑定到值被认为是同样好的(两者都是重载决策中的"完全匹配"),因此不推导出参数的引用.相反,您必须准确指定它.对于相关示例,请考虑假设的构造
T x = f();
Run Code Online (Sandbox Code Playgroud)
在T
这个思想实验的持续时间里,你应该推断出什么.应该x
是什么- 一个对象或一个引用?它取决于什么?当然,右边的表达式有一个值,该值的类型始终是对象类型.你应该如何决定?您可以查询表达式的值类别,但这太微妙了.所以相反,你必须说出你想要的东西:
T x = f(); // x is an object
T & r = f(); // r is a reference
Run Code Online (Sandbox Code Playgroud)
在C++中,如果替换为T
,则实际上可以使用此机制auto
.相同的规则适用于函数模板的模板参数推导.
现在就如何解决你的问题.通常的习惯用法是让函数模板始终采用引用,然后将参数转发给内部调用:
template <typename T>
void func(T && t)
{
f(std::forward<T>(t));
};
Run Code Online (Sandbox Code Playgroud)
现在func
的参数总是在任何专门的引用(但由于一个奇怪的规则称为'参考塌陷’,它可以是一个左值或右值参考),并且该值被转发具有相同值的类别组到f
,并且这过载分辨率f
允许当原始参数来选择左值引用过载func
是一个左值.
使用转发参考:
template<typename T>
void func(T && p) //notice &&
{
f(std::forward<T>(p)); //notice std::forward
}
Run Code Online (Sandbox Code Playgroud)
现在请搜索转发引用(或之前提到的通用引用)以及std::forward
此站点以了解有关它们的更多信息.
归档时间: |
|
查看次数: |
1004 次 |
最近记录: |