C++ 模板无法在不使用"&"的情况下推断引用类型
C++ Templates can't deduce Reference Types without using '&'
这是一个非常简单的例子:
#include <iostream>
template<typename T>
void DoubleMe(T x) {
x += x;
}
int main()
{
int a = 10;
DoubleMe(a);
std::cout << a; //displays 10 not 20!
}
在这种情况下,我是否被迫在函数参数中使用"T&"?因为我在一些教程中读到,模板可以通过在变量前定义一个简单的"T"来正确推断出适当的数据类型,包括 T*、T[ ] 或 T&。帮助?
也许这将帮助您以编译器的方式看待它(如果我过于简化,请向任何语言律师道歉(:
在此示例中,编译器必须推断 T 的类型是使函数声明合法且扣除量最少的类型。由于 T 通常可以直接从 const T&进行复制构造(这意味着它也可以从 T&进行复制构造(,因此您的函数将获取副本。
template<class T>
void foo(T value);
在此示例中,T 必须是 ref
引用的对象事物的类型 - 并且由于引用不能引用引用,因此 T 必须是(可能是常量,可能是易失性(类型。
template<class T>
void foo(T& ref);
在此示例中,ref 必须引用类型 T 的 const(可能是易失性(对象:
template<class T>
void foo(const T& ref);
在此示例中,ref
可以是引用或 r 值引用。它被称为通用参考。您实际上是在一个函数中编写两个函数,这通常是处理您拥有ref
的情况的最有效方法。
template<class T>
void foo(T&& ref);
// called like this:
foo(Bar()); // means ref will be a Bar&&
// called like this:
Bar b;
foo(b); // means ref will be a Bar&
// called like this:
const Bar b;
foo(b); // means ref will be a const Bar&
总结:
void foo(T value)
的意思是我会复制你给我的东西。
void foo(T& value)
意味着我不会复制,但我可能会修改您的值。你不许给我一个临时的。
void foo(const T& value)
意味着我不会复制,也无法修改您的副本。你可以给我一个临时的。
void foo(const T&& value)
意味着我可以窃取或修改您的值的内容,即使它是暂时的。
您确实可以使用普通T
正确推断引用类型。不幸的是,这并不意味着你认为它的意思。
鉴于
template <typename T> struct S { };
template <typename T> void f(S<T>) { }
int main() { f(S<int&>{}); }
f
的类型参数被正确地推导为 int&
。
问题是,在您的情况下,将T
推断为int
已经产生了一个完全有效的函数。也许有点过于简单,但类型推导会产生使调用工作的最简单的T
。在您的情况下,T = int
使呼叫正常工作。不是您希望它工作的方式,但编译器无法知道这一点。 T = int &
也会使调用工作,但这不是使其工作的最简单的T
。
是的,要在此处获得所需的效果,必须添加与号。
编写时,模板可以正确推断数据类型。但是,他们无法推断出意图。在这种情况下,您传递给它的类型是一个整数,它正确地实例化了一个整数函数,该函数在内部按值将传递给它的参数加倍。事实上,你的意思是函数有副作用,这不是编译器可以猜到的。
如果希望函数按值传递参数,则需要返回具有相同参数类型的值。
T DoubleMe(T x) {
return x + x;
}
- 在没有太多条件句的情况下,我如何避免被零除
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 在未初始化映射的情况下,将值插入到映射的映射中
- 是默认情况下分配给char数组常量的值
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 如何在不产生任何垃圾的情况下获得C中的像素
- 在已经使用Git的情况下减少编译时间
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 如何在没有信号的情况下从C++执行QML插槽
- 如何在不知道向量大小的情况下输入向量内部的向量?
- 为什么在某些情况下不写入此文件?
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 在没有Xcode的情况下在Mac捆绑包中嵌入框架
- UE4-如何在给定4个屏幕坐标的情况下缩放纹理或材质
- C++去除前x个元素的有效方法,在不改变向量大小的情况下将第x+1个元素推到第一个
- 我可以在不推送向量的情况下向向量添加值吗?
- 我们可以在不使用构造函数的情况下推回包含矢量的结构
- C++ 队列在没有推送的情况下弹出
- 如何在没有整个助推的情况下使用boost.xpressive
- 如何在<string>不推送的情况下创建矢量或类似内容?