- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
是否可以防止从参数包扩展的参数中的数组到指针衰减?
例如:
#include <iostream>
void foo() {
std::cout << "empty\n";
}
template <typename T, typename... Rest>
void foo(T &&t, Rest... rest) {
std::cout << "T, ...\n";
foo(rest...);
}
template <typename... Rest>
void foo(char *p, Rest... rest) {
std::cout << "char*, ...\n";
foo(rest...);
}
template <int N, typename... Rest>
void foo(char (&first)[N], Rest... rest) {
std::cout << "char[], ...\n";
foo(rest...);
}
int main() {
char a[2], b[2], c[2];
foo(a, b, c);
}
...输出:
char[], ...
char*, ...
char*, ...
empty
如您所见,第一次调用转到基于数组的重载,但后续调用转到基于指针的重载。 有什么方法可以让所有调用转到基于数组的重载吗?
最佳答案
您想通过右值引用传递参数包:
void foo(char (&first)[N], Rest&&... rest)
^^
所以整个代码看起来是这样的:
#include <iostream>
void foo() {
std::cout << "empty\n";
}
template <typename T, typename... Rest>
void foo(T &&t, Rest... rest) {
std::cout << "T, ...\n";
foo(rest...);
}
template <typename... Rest>
void foo(char *p, Rest... rest) {
std::cout << "char*, ...\n";
foo(rest...);
}
template <int N, typename... Rest>
void foo(char (&first)[N], Rest&&... rest) {
std::cout << "char[], ...\n";
foo(rest...);
}
int main() {
char a[2], b[2], c[2];
foo(a, b, c);
}
给出结果:
char[], ...
char[], ...
char[], ...
empty
我没有更改其他重载来执行相同的操作,但您通常希望它们也使用右值引用(如果它们确实被使用的话)。
编辑:至于为什么要这样做/为什么它有效:右值引用可以绑定(bind)到右值或左值。我们在这里关心的关键点是当它绑定(bind)到一个左值时,它仍然是一个左值。在数组的情况下,它保留其作为数组的身份,因此接收到的是一个数组。
当/如果我们按值传递数组时,它会经历正常的指针“衰减”,就像普通函数一样。
对于这种特定情况,我们也可以使用普通的左值引用——但如果我们这样做,那将不适用于任何不是左值的类型。例如,如果我们试图调用 foo(1,2,3);
,我们会得到一个错误,因为左值引用不能绑定(bind)到 1
,2
或 3
。为了解决这个问题,我们可以传递一个 const
左值引用,但是这样我们就不会将引用直接绑定(bind)到右值——我们会创建一个临时包含传递的右值的拷贝,然后将左值引用绑定(bind)到该临时拷贝。对于 int 的特定情况,这可能不是主要问题,但对于复制成本更高的东西(或者如果我们想要访问原始文件,而不是拷贝),这可能是个问题。
关于c++ - 防止参数包扩展中的数组衰减,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13922145/
liwen01 2024.08.18 前言 无论是在产品开发还是在日常生活中,在使用无线网络的时候,都会经常遇到一些信号不好的问题,也会产生不少疑问: 为什么我们在高速移动的高铁上网络会变
我正在使用 Kinect 获取每个关节的位置和方向,然后将它们发送到 Unity。我注意到值有很多“跳跃”或波动,例如,有时我不移动我的手,而在 Unity 中它会旋转 180 度。 我想要的是一个平
在下面的示例中, #include #include //okay: // template decltype(auto) runner(T&& t, F f) { return f(st
出于某种原因,即使我设置了衰减因子,我的学习率似乎也没有改变。我添加了一个回调来查看学习率,它似乎在每个纪元之后都是一样的。为什么没有变化 class LearningRatePrinter(Call
考虑下面的代码: #include #include using namespace std; template void Test2(future f, Work w) { async([
我是一名优秀的程序员,十分优秀!