类型体系与基本数据类型(题目)

目录

1.  本章讨论了标签的用法。在我们经常使用的标准模板库(STL)中也存在标签的概念。STL将迭代器进行了划分,为不同的迭代器赋予了不同的标签(如双向迭代器、随机访问迭代器等)。在网络上搜索一下相关的概念,学习并了解STL中标签的用法,并于本章中标签的用法进行比较。

双向迭代器

随机访问迭代器

STL中的标签用法

2.  在本章中,我们讨论了使用函数参数或模板参数传递类别标签。STL将标签作为函数参数进行传递,这样做的一个好处是可以自动处理标签的继承关系。STL中的迭代器标签具有派生层次,比如前向迭代器是一种特殊的输入迭代器,这体现在标签体系中,是表示前向迭代器的标签forward_iterator_tag派生自input_iterator_tag。而对于本章所讨论的_distance实现来说,如果传入其中的第3个参数是前向迭代器,那么编译器会自动选择输入迭代器的版本进行计算。如果像本章所讨论的那样,使用模板参数来传递迭代器标签,则不能简单地通过std::is_same进行比较来实现类似的效果。请尝试引入新的元函数,在使用模板参数传递迭代器类别的算法中实现类似的标签匹配效果。更具体来说,实现的元函数应当具有如下调用方式:

3.  使用模板参数而非函数参数来传递标签信息还有另一个好处,我们不再需要提供标签类型的定义了。为了基于函数参数来传递标签信息,STL不得不引入类似下面的类型定义:

4.  STL提供了一个元函数is_base_of,用来判断某个类是否是另一个类的基类,使用这个元函数,修改第2章的_distance声明,使其更加简洁。基于修改后的元函数声明,再次考虑第3题:此时,我们是否需要迭代器标签的类型定义呢?为什么?

5.  在讨论DataCategory_的实现时,我们为其引入了一个名为helper的辅助元函数。它是声明在DataCategory_内部的。尝试将其提取到DataCategory_的外部。思考一下这种改进是否会像第一1章所讨论的那样,减少编译过程中所构造的实例数。尝试验证你的想法。

6.  本章介绍了MetaNN所使用的矩阵类Matrix,考虑如下声明:

7.  在子矩阵的讨论中,我们通过引入m_rowLen来确定两行的间距,除了这种方式,还可以标记连续两行中上一行结尾与下一行的开始之间的元素个数。考虑这种方式与本书所采用的方式之间的优劣。

8.  阅读并分析Batch、Array与Duplicate中针对标量的实现代码

9.  阅读并分析OneHotVector与ZeroMatrix的实现代码。

10.  ArrayImp的一个构造函数引入了元函数IsIterator来确保输入的参数是迭代器。能否去掉这个元函数,采用下面的函数声明:

11.  我们在讨论ArrayImp时,提到了在求值之后就不能进行修改。那么Matrix或者Batch类模板是否存在同样的问题呢?事实上,这两个模板有些特殊,即使是求值了之后再进行修改,其语义也是正确的。考虑一下原因。


1.  本章讨论了标签的用法。在我们经常使用的标准模板库(STL)中也存在标签的概念。STL将迭代器进行了划分,为不同的迭代器赋予了不同的标签(如双向迭代器、随机访问迭代器等)。在网络上搜索一下相关的概念,学习并了解STL中标签的用法,并于本章中标签的用法进行比较。

双向迭代器

双向迭代器是一种迭代器,它可以在容器中向前和向后遍历元素。它具备了向前迭代器的特性,可以使用递增运算符(++)向前移动,以及向后迭代器的特性,可以使用递减运算符(--)向后移动。

C++代码示例,展示了如何使用双向迭代器来遍历一个容器(例如vector)中的元素:

#include <iostream>
#include <vector>int main() {std::vector<int> numbers = {1, 2, 3, 4, 5};// 使用双向迭代器向前遍历std::cout << "向前遍历:";for (auto it = numbers.begin(); it != numbers.end(); ++it) {std::cout << " " << *it;}// 使用双向迭代器向后遍历std::cout << "\n向后遍历:";for (auto it = numbers.rbegin(); it != numbers.rend(); ++it) {std::cout << " " << *it;}return 0;
}

此代码演示了通过使用`begin()`和`end()`方法获取双向迭代器来遍历vector容器中的元素。第一个循环使用递增运算符向前遍历,第二个循环使用递减运算符向后遍历。请注意,`rbegin()`和`rend()`方法返回的是逆向的双向迭代器,以实现向后遍历。

随机访问迭代器

随机访问迭代器是一种迭代器,它具有在常量时间内跳转到容器中的任何位置的能力,并支持以常量时间进行算术运算(如加法和减法),以便在容器中定位元素。随机访问迭代器还可以使用指针算术运算符(例如`[]`)直接访问容器中的元素。

C++代码示例,展示了如何使用随机访问迭代器来遍历一个数组:

#include <iostream>
#include <vector>int main() {std::vector<int> numbers = {1, 2, 3, 4, 5};// 使用随机访问迭代器遍历std::cout << "遍历数组:";for (auto it = numbers.begin(); it != numbers.end(); ++it) {std::cout << " " << *it;}// 使用随机访问迭代器进行指针算术运算std::cout << "\n通过随机访问迭代器直接访问元素:";std::cout << " " << numbers[0];std::cout << " " << numbers[1];std::cout << " " << numbers[2];std::cout << " " << numbers[3];std::cout << " " << numbers[4];return 0;
}

此代码演示了如何使用`begin()`和`end()`方法获取随机访问迭代器来遍历vector容器中的元素。随机访问迭代器具有与指针相似的行为,可以使用递增运算符`++`和递减运算符`--`在容器中移动,并使用指针算术运算符`[]`直接访问元素。

STL中的标签用法

在STL(标准模板库)中,标签(Tag)是一种用于区分不同算法或函数重载的机制。标签通常以类型为参数的形式出现,以便在编译时根据标签来选择适当的函数或算法。标签可以是自定义的结构体、类或枚举类型。

STL标签的使用示例:1. 迭代器标签:STL中的算法通常接受一个迭代器范围来操作容器中的元素。迭代器标签用于指定迭代器的类型,以便算法知道如何处理它们。例如,`std::sort`算法有两个重载,一个接受随机访问迭代器,一个接受双向迭代器:

template <class RandomIt>
void sort(RandomIt first, RandomIt last);template <class BidirIt>
void sort(BidirIt first, BidirIt last);

在这里,`RandomIt`和`BidirIt`就是迭代器标签,它们用于区分不同的重载版本。

2. 容器标签:STL中的一些算法和函数根据不同的容器特性进行优化。容器标签用于指定容器的类型,以便选择相应的实现。例如,`std::back_inserter`函数用于在容器的末尾插入元素:

template<class Container>
std::back_insert_iterator<Container> back_inserter(Container& c);

在这里,`Container`就是容器标签,它指定了`back_inserter`函数适用的容器类型。3. 数值标签:STL中的数值算法(如`std::accumulate`和`std::inner_product`)可以接受数值标签,以指定用于计算的数值类型。例如,`std::accumulate`算法有以下两个重载:

template<class InputIt, class T>
T accumulate(InputIt first, InputIt last, T init);template<class InputIt, class T, class BinaryOp>
T accumulate(InputIt first, InputIt last, T init, BinaryOp op);

第一个重载的数值标签使用`T`,而第二个重载可以通过指定额外的`BinaryOp`参数来定义特定的数值计算操作。

这些示例展示了STL中标签的使用方式。标签可以帮助算法或函数在编译时选择正确的实现,提高代码效率和可读性。

本章中标签的用法进行比较,就留给你们思考!!!

2.  在本章中,我们讨论了使用函数参数或模板参数传递类别标签。STL将标签作为函数参数进行传递,这样做的一个好处是可以自动处理标签的继承关系。STL中的迭代器标签具有派生层次,比如前向迭代器是一种特殊的输入迭代器,这体现在标签体系中,是表示前向迭代器的标签forward_iterator_tag派生自input_iterator_tag。而对于本章所讨论的_distance实现来说,如果传入其中的第3个参数是前向迭代器,那么编译器会自动选择输入迭代器的版本进行计算。如果像本章所讨论的那样,使用模板参数来传递迭代器标签,则不能简单地通过std::is_same进行比较来实现类似的效果。请尝试引入新的元函数,在使用模板参数传递迭代器类别的算法中实现类似的标签匹配效果。更具体来说,实现的元函数应当具有如下调用方式:

template<typename TIterTag,typename _InputIterator,enable_if_t <FUN<TIterTag,input_iterator_tag,forward_iterator_tag,bidirectional_iterator_tag>>*= nullptr>
inline auto _distance(_InputIterator b, _InputIterator e);

其中FUN是需要实现的元函数,上述调用表面,如果TIterTag是input_iterator_tag(输入迭代器),forward_iterator_tag(前向迭代器)或者bidirectional_iterator_tag(双向迭代器)之一,编译器就会选择当前的_distance版本。

为了实现通过模板参数传递迭代器标签并进行标签匹配的效果,可以使用SFINAE(Substitution Failure Is Not An Error)技术和模板特化。

首先,定义一个元函数 `FUN` ,用于检查一个迭代器标签是否匹配所需的标签:
 

template<typename T, typename U>
struct is_same_tag {static constexpr bool value = false;
};template<typename T>
struct is_same_tag<T, T> {static constexpr bool value = true;
};template<typename TIterTag, typename TInputIter,typename = std::enable_if_t<is_same_tag<TIterTag, typename std::iterator_traits<TInputIter>::iterator_category>::value>>
struct FUN {static constexpr bool value = true;
};

然后,在 `_distance` 函数中使用该元函数进行标签匹配。根据传入的 `TIterTag` 参数的类型,选择相应的算法版本。

template<typename TIterTag, typename TInputIterator,typename std::enable_if_t<FUN<TIterTag, TInputIterator>::value>* = nullptr>
inline auto _distance(TInputIterator b, TInputIterator e) {// 实现具体的距离计算逻辑// ...
}

通过对 `TIterTag` 和 `std::iterator_traits` 的 `iterator_category` 进行比较,可以实现对迭代器标签进行匹配,并选择正确的 `_distance` 版本。

template<typename TIterTag, typename TInputIterator,typename = std::enable_if_t<FUN<TIterTag, TInputIterator>::value>>
inline auto _distance(TInputIterator b, TInputIterator e) {// 实现具体的距离计算逻辑// ...
}int main() {std::vector<int> vec = {1, 2, 3, 4, 5};// 使用输入迭代器标签进行计算auto dist = _distance<std::input_iterator_tag>(vec.begin(), vec.end());// 使用前向迭代器标签进行计算auto dist2 = _distance<std::forward_iterator_tag>(vec.begin(), vec.end());// 使用双向迭代器标签进行计算auto dist3 = _distance<std::bidirectional_iterator_tag>(vec.begin(), vec.end());return 0;
}

这样,根据传入的迭代器标签类型,编译器会自动选择 `_distance` 的适当版本进行距离计算。

3.  使用模板参数而非函数参数来传递标签信息还有另一个好处,我们不再需要提供标签类型的定义了。为了基于函数参数来传递标签信息,STL不得不引入类似下面的类型定义:

struct output_iterator_tag {};

但如果使用模板参数来传递标签,相应的类型定义就可以被省略:

struct output_iterator_tag;

分析一下为什么会这样

当使用模板参数而非函数参数来传递标签信息时,不需要提供标签类型的定义的原因如下:

1. 编译器根据传递给模板参数的具体类型来确定标签的类型。例如,使用模板参数 `T` 来传递迭代器标签,可以根据 `T` 的类型来确定具体是哪个标签,而不需要提前定义 `struct output_iterator_tag {}` 这样的类型。

2. 模板参数是一种编译时的机制,编译器可以根据模板实例化的具体类型来进行类型推断和选择代码路径。模板参数本身就代表了某个类型,因此不需要进行额外的类型定义。

3. 类型定义(例如 `struct output_iterator_tag {}`)在传递标签信息和进行类型匹配中起到了辅助作用。而对于模板参数来说,传递类型信息和进行类型匹配是自然的一部分,不需要专门定义一个结构体。

因此,当使用模板参数来传递标签信息时,不需要提供类似于 `struct output_iterator_tag {}` 这样的类型定义。编译器可以根据传递给模板参数的具体类型来确定标签的类型,从而避免了额外的类型定义和冗余的代码。

4.  STL提供了一个元函数is_base_of,用来判断某个类是否是另一个类的基类,使用这个元函数,修改第2章的_distance声明,使其更加简洁。基于修改后的元函数声明,再次考虑第3题:此时,我们是否需要迭代器标签的类型定义呢?为什么?

留给你们思考!!!

5.  在讨论DataCategory_的实现时,我们为其引入了一个名为helper的辅助元函数。它是声明在DataCategory_内部的。尝试将其提取到DataCategory_的外部。思考一下这种改进是否会像第一1章所讨论的那样,减少编译过程中所构造的实例数。尝试验证你的想法。

留给你们思考!!!

6.  本章介绍了MetaNN所使用的矩阵类Matrix,考虑如下声明:

vector<Matrix<int, DeviceTags::CPU>> a(3, {2, 5});

我们的本意是声明一个变量,包含3个矩阵。之后,我们希望对向量中的3个矩阵分别赋值。考虑一下这种做法是否行得通?如果不行,会有什么问题(提示:MetaNN中的矩阵是浅拷贝的)?

在MetaNN中,矩阵类 `Matrix` 是浅拷贝的,这意味着拷贝构造函数和拷贝赋值运算符只会复制矩阵的结构和元数据,而不会复制矩阵的数据本身。因此,尝试对向量中的每个矩阵进行赋值是有问题的。

在以下代码中:

vector<Matrix<int, DeviceTags::CPU>> a(3, {2, 5});

`vector` 将使用默认拷贝构造函数来创建 `a` ,其中每个元素都被拷贝了三次,但是这些拷贝的矩阵都指向相同的数据。

因此,如果尝试对向量中的每个矩阵进行分别赋值,由于所有矩阵共享相同数据内存,赋值操作将影响到所有矩阵。这可能导致意外结果,并且不符合最初的意图。

要分别对每个矩阵赋值,需要确保每个矩阵都拥有自己的独立数据。可以通过使用不同的矩阵对象来实现,或者通过手动创建每个矩阵的副本来确保数据的独立性。

7.  在子矩阵的讨论中,我们通过引入m_rowLen来确定两行的间距,除了这种方式,还可以标记连续两行中上一行结尾与下一行的开始之间的元素个数。考虑这种方式与本书所采用的方式之间的优劣。

留给你们思考!!!

8.  阅读并分析Batch、Array与Duplicate中针对标量的实现代码

留给你们分析!!!

9.  阅读并分析OneHotVector与ZeroMatrix的实现代码。

留给你们分析!!!

10.  ArrayImp的一个构造函数引入了元函数IsIterator来确保输入的参数是迭代器。能否去掉这个元函数,采用下面的函数声明:

template <typename TIterator>
ArrayImp(TIterator b, TIterator e)

为什么?

留给你们思考!!!

11.  我们在讨论ArrayImp时,提到了在求值之后就不能进行修改。那么Matrix或者Batch类模板是否存在同样的问题呢?事实上,这两个模板有些特殊,即使是求值了之后再进行修改,其语义也是正确的。考虑一下原因。

在MetaNN中,Matrix和Batch类模板与ArrayImp不同,即使在求值之后进行修改也是语义上合理的。这是因为Matrix和Batch是“动态计算”模板,其内部包含延迟计算机制。

1. Matrix类模板:Matrix在进行加法、乘法、转置等操作时,并不立即执行计算,而是构建了对应的计算图。只有在需要结果时,才会进行实际的计算(即求值)。因此,即使在求值之后对Matrix进行修改,只需重新求值计算即可,其语义仍然是正确的。

2. Batch类模板:Batch类模板适用于批量数据的处理,具有类似于Matrix的延迟计算机制。它可以表示由多个矩阵组成的批量数据,并支持各种批量操作。同样,即使在求值之后对Batch进行修改,也可以通过重新求值来重新计算批量操作的结果。

这种延迟计算的机制使得Matrix和Batch类模板更加灵活和高效,可以在保持数据一致性的前提下进行修改。当需要结果时,再进行计算和求值。这种设计允许用户在动态计算模型中进行灵活的修改和调整。

总结而言,Matrix和Batch类模板具有延迟计算机制,允许在求值之后进行修改,并通过重新求值来重新计算结果,保持语义上的正确性。这使得它们在表示动态计算模型和处理批量数据时更加灵活和强大。

12.  本章所讨论的数据结构中,有一些包含了EvalBuffer这样的数据成员,用于存储求值之后的结果。但像Matrix这样的类模板就没有包含类似的数据成员。思考一下原因。

Matrix类模板没有包含类似EvalBuffer的数据成员,是因为Matrix的求值结果直接存储在矩阵对象本身。

在MetaNN中,Matrix是动态计算模板,当进行加法、乘法、转置等操作时,并不立即执行计算,而是构建了对应的计算图。只有在需要结果时,才会进行实际的计算(即求值)。而计算的结果会直接存储在Matrix对象中,而不需要额外的数据成员来存储求值结果。

当Matrix进行求值之后,其内部的数据会被更新为求值的结果,这样就可以直接通过Matrix对象来访问和操作计算结果。因此,不需要像EvalBuffer那样的额外数据成员来存储求值结果。

这种设计使得Matrix的使用更加简洁和高效,避免了额外的内存开销和数据拷贝操作。求值结果直接存储在Matrix对象中,可以直接通过对象来访问,提高了代码的可读性和执行效率。

总结而言,Matrix类模板没有包含EvalBuffer类似的数据成员,是因为Matrix的求值结果直接存储在矩阵对象本身。这种设计使得Matrix的使用更加简洁高效,并且避免了额外的内存开销和数据拷贝操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/155258.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android Serializable / Parcelable

Serializable 序列化,将对象转为二进制序列 Parcelable 不是序列化,属于进程间通信,不需要IO/操作,没有拷贝内存的操作, Object -> ShareMemory -> Object 不需要IO,使用内存共享等方式 Kotlin inline fun 内联函数 TCP协议将数据包拆分,进行发送,保证网络数据的可…

基于纹理特征的kmeas聚类的图像分割方案

Gabor滤波器简介 在图像处理中&#xff0c;以Dennis Gabor命名的Gabor滤波器是一种用于纹理分析的线性滤波器&#xff0c;本质上是指在分析点或分析区域周围的局部区域内&#xff0c;分析图像中是否存在特定方向的特定频率内容。Gabor滤波器的频率和方向表示被许多当代视觉科学…

二十一、数组(3)

本章概要 Arrays的setAll方法增量生成 Arrays的setAll方法 在Java 8中&#xff0c; 在RaggedArray.java 中引入并在 ArrayOfGenerics.java.Array.setAll() 中重用。它使用一个生成器并生成不同的值&#xff0c;可以选择基于数组的索引元素&#xff08;通过访问当前索引&…

00、计算机视觉入门与调优简介

写在前面 每天更新1篇文章&#xff0c;共更新100篇以上 相关代码会放在gitee上 中间会按进度和反馈安排视频讲解 预计2023-11-11开始推送文章&#xff0c;持续3个月左右 专栏简介 本专栏带你从头开始入门计算机视觉。 内容会比之前写的文章更专业更全面&#xff0c;并且你…

Android项目更新依赖和打包步骤和问题汇总

目录 1、Android 项目打包&#xff0c;32位包升级到64位包问题一&#xff1a;ERROR: Conflicting configuration : armeabi-v7a,x86-64,arm64-v8a,x86 in ndk abiFilters cannot be present when splits abi filters are set : x86,armeabi-v7a,arm64-v8a 2、Android项目依赖升…

docker部署excalidraw画图工具(银角大王课堂使用的画图软件搭建)

环境搭建 安装docker&#xff08;不过多说&#xff0c;可以参照他人文档&#xff09; 安装docker-compose 运行以下命令以下载 Docker Compose 的当前稳定版本&#xff1a; sudo curl -L "https://github.com/docker/compose/releases/download/v2.2.2/docker-compose…

pytest-base-url插件之配置可选的项目系统URL

前言 ①当我们的自动化代码完成之后&#xff0c;通常期望可以在不同的环境进行测试&#xff0c;此时可以将项目系统的URL单独拿出来&#xff0c;并且可以通过pytest.ini配置文件和支持pytest命令行方式执行。 ② pytest-base-url 是一个简单的pytest插件&#xff0c;它通过命…

【数据结构】HashMap 和 HashSet

目录 1.哈希表概念 2冲突 2.1概念 2.2 冲突-避免 2.3冲突-避免-哈希函数设计 2.4 冲突-避免-负载因子调节 ​编辑 2.5 冲突-解决-开散列/哈希桶 2.5冲突严重时的解决办法 3.实现 4.性能分析 5.与Java集合类的关系 1.哈希表概念 在顺序结构中&#xff0c;元素关键码和存…

【vue+eltable】修改表格滚动条样式

<style lang"scss" scoped> ::v-deep .el-table__body-wrapper::-webkit-scrollbar {width: 10px; /*纵向滚动条的宽度*/height: 10px; /*横向滚动条的高度*/ } /*定义滚动条轨道 内阴影圆角*/ ::v-deep .el-table__body-wrapper::-webkit-scrollbar-track {bo…

Java 多线程之 volatile(可见性/重排序)

文章目录 一、概述二、使用方法三、测试程序3.1 验证可见性的示例3.2 验证指令重排序的示例 一、概述 在Java中&#xff0c;volatile 关键字用于修饰变量&#xff0c;其作用是确保多个线程之间对该变量的可见性和禁止指令重排序优化。 当一个变量被声明为volatile时&#xff0…

高德地图点击搜索触发输入提示

减少调用次数&#xff0c;不用每输入一次调用一次&#xff0c;输入完后再触发搜索 效果图&#xff1a; ![Alt](https://img-home.csdnimg.cn/images/20220524100510.png dom结构 <div class"seach"><van-searchshow-actionv-model"addressVal"…

【使用vscode在线web搭建开发环境--code-server搭建】

官方版本下载 https://github.com/coder/code-server/releases?q4.0.0&expandedtrue使用大于版本3.8.0,因为旧版本有插件市场不能访问的情况版本太高需要更新环境依赖 拉取安装包 []# wget "https://github.com/coder/code-server/releases/download/v4.0.0/code-…

探访九牧绿色黑灯工厂,找寻“科技卫浴 世界九牧”的答案

文 | 螳螂观察 作者 | 余一 你所想象中的工厂是怎么样的&#xff1f;灯火通明、人声鼎沸、人来人往&#xff1f;如果告诉你一座工厂既没有灯&#xff0c;也没有人&#xff0c;但却还在持续生产&#xff0c;你会不会觉得这是不可思议的事&#xff1f; 如果不是亲眼见证&#…

Simulink 自动代码生成:手写代码替换生成代码Code Replacement Tool使用

目录 前言 代码替换库操作步骤 代码生成验证 总结 前言 在实际工程开发过程中&#xff0c;Simulink生成的代码都是构建的算法实现的&#xff0c;纯软件实现&#xff0c;生成的代码大多也是直接在CPU上运行的。实际还有一些MCU集成了像Cordic&#xff0c;协处理器等。有些代…

WinEdt 11.1编辑器的尝鲜体验

WinEdt 11.1编辑器的尝鲜体验 2023年5月19日&#xff0c;WinEdt 11.1版本发布了&#xff0c;相比WinEdt 10.3, 最新版更加漂亮&#xff0c;更加友好&#xff0c;更加好用了&#xff01; 最大的改变是WinEdt 11.1 有了自带的WinEdtPDF阅读器&#xff0c;所以不再需要下载第三方…

ros2工作空间

我们先不管ros2工作空间是什么样子的&#xff0c;如果是我自己来搞一个工作空间&#xff0c;我一定是这样安排 一个文件夹用来放自己存放的文件&#xff0c;。。。。。。。。。。对应src文件夹 一个文件夹用来放编译后的文件&#xff0c;。。。。。。。。。。。对应intall文件…

模型微调技术

Parameter Efficient Fine Tuning (PEFT)和Low Rank Adaptation (LoRA)是2种非常重要的模型微调方法。这两种方法只微调模型的一小部分&#xff08;额外的&#xff09;参数&#xff0c;同时冻结预训练模型的大部分参数&#xff0c;从而大大降低了计算和存储成本。尤其是LoRA&am…

day61 layui和分页原理

昨日内容回顾 choices参数的使用 一般用在什么场景&#xff1a;当被存储的字段数据可能被列举完毕的时候一般会使用choices参数 性别 学历 来源 工作经验等 一般情况下不在数据表中直接存储中文&#xff0c;存数字、存字母来做映射 # 怎么使用 gender_choices ((1, 男),(2…

Weakly Supervised Visual Question Answer Generation

目录 一、论文速读 1. 1 论文概要总结 相关工作 主要贡献 论文主要方法 实验数据 未来研究方向 二、论文精度 2.1 论文试图解决什么问题&#xff1f; 2.2 论文中提到的解决方案之关键是什么&#xff1f; 2.3 用于定量评估的数据集是什么&#xff1f;代码有没有开源&a…

各语言语法

一些语法格式的特点&#xff1a; Html: <></> xx”” json: { “”:””, } 数组中可以嵌套对象&#xff0c;数组 css: xx{ //代表某些符号&#xff0c;比如. xxx:yyy; } JS 1.function test( ){ } 2.Const testfunction( ){ } //定义…