编写接受可变跨度作为不可变跨度的模板函数
Write template function that accepts mutable span as an immutable span
gsl::span是一段内存的视图。
foo
是一个模板函数,可以接受可变范围和不可变范围。
我希望 foo
中的代码始终只能对块内存进行不可变的访问。
#include <gsl/gsl> // gsl-lite
template <typename T>
void foo(gsl::span<const T> x) {}
int main() {
int arr[] = {0, 1, 2, 3, 4};
auto s1 = gsl::span<int>(arr);
foo(s1);
}
这不起作用,因为在模板实例化期间没有类型转换。
如果我写以下内容:
template <typename T>
void foo(gsl::span<T> x) {}
在foo
内,x
可以是一个可变的跨度。
此用例的正确修复方法是什么?
gsl::span<const T>
具有接受gsl::span<T>
的构造函数。所以你"只是"有一个模板推导的问题。
您可以通过多种方式解决问题:
-
在调用站点明确:
- 呼叫
foo<int>(arr)
- 或致电
foo(gsl::span<const int>(arr))
- 呼叫
-
写入重载:
template <typename T> void foo(gsl::span<const T> arr) { /* Your implementation */ } template <typename T> void foo(gsl::span<T> arr) { foo(gsl::span<const T>(arr)); }
-
编写帮助程序函数,使其在调用站点不太明确,例如:
template <typename T> span<const T> as_immutable_view(span<T> s) { return s; }
然后呼叫
foo(as_immutable_view(arr))
如何从
参数中制作变量的常量版本?
template <typename T>
void foo(gsl::span<T> x_raw)
{
gsl::span<const T> x { x_raw }; // add const if not already present
// use x in the code
}
相关文章:
- 为什么使用SFINAE而不是函数重载
- 正在寻找C++不可变的hashset/hashmap
- 回溯C++不打印函数,因此文件
- () 函子后面的括号,而不是函数指针?
- 程序不向函数返回值
- LLVM 选择找不到函数传递
- C++有什么方法可以在既不调用函数模板也不提供其模板参数的情况下引用函数模板?
- 在这种情况下,如何传递成员函数而不是函数?
- 具有常量属性的不可变类
- 提升堆栈跟踪不显示函数名称和行号
- C++线程找不到函数作为参数(链接器)
- 调用参数排列不变函数 f(i++, i++)
- 返回不停止函数,递归函数问题?(编程练习,动态规划,Levenshtein 回溯)
- 为什么将函数传递给内核会导致数据变得不可变?
- 编写接受可变跨度作为不可变跨度的模板函数
- 不可变的 lambda 函数:复制捕获的变量是否允许是 const
- 如何将真正不可变的 2D 数组传递给函数?
- 可变函数指针参数的模板参数推导-处理不明确的情况
- C++返回不可变指针向量的函数语法
- 可变函数模板基本情况:不带参数或带参数