gpt4 book ai didi

c++ - 如何使模板类型推导与引用一起工作?

转载 作者:可可西里 更新时间:2023-11-01 18:15:46 30 4
gpt4 key购买 nike

我有一个模板函数,func:

template<typename T>
void func(T p) { f(p); }

还有一组函数f:

f(SomeType&);
f(int);
...

如果我实例化模板函数 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

所以,我的问题是:

  • 为什么在上述情况下编译器无法推导出引用类型SomeType&
  • 有没有一种方法可以定义模板函数 func,这样类型推导就可以使用引用类型,而无需显式指定模板参数 T

明确地说,我想要同时使用两者的东西(参见上面的函数 f):

func(ref_to_s);    // Calls func<SomeType&>(ref_to_s)
func(1); // Calls func<int>(1)

最佳答案

第一部分的答案是,从一个值初始化一个对象和将一个引用绑定(bind)到一个值被认为是同样好的(在重载决策中都是“精确匹配”),因此不推导出参数的引用.相反,您必须准确指定它。对于一个相关的例子,考虑一个假设的结构

T x = f();

其中 T 是(在这个思想实验期间)你应该推断的东西。 x 应该是什么——一个对象,还是一个引用?这取决于什么?右边的表达式当然有一个值,并且该值的类型始终是对象类型。你应该如何决定?您可以查询表达式的值类别,但这太微妙了。因此,必须说出您想要的内容:

T x = f();    // x is an object
T & r = f(); // r is a reference

在 C++ 中,如果将 T 替换为 auto,则此机制实际上可用。相同的规则适用于函数模板的模板参数推导。

现在介绍如何解决您的问题。通常的习惯用法是让函数模板总是接受一个引用,然后将参数转发给内部调用:

template <typename T>
void func(T && t)
{
f(std::forward<T>(t));
};

现在 func 的参数在任何特化中总是一个引用(但是由于一个叫做“引用折叠”的奇怪规则,它可以是一个左值或一个右值引用),并且那个值是将 具有相同值类别组 转发给 f,并且此对 f 的重载解析允许在原始参数用于时选择左值引用重载func 是一个左值。

关于c++ - 如何使模板类型推导与引用一起工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37068969/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com