突破编程_C++_C++11新特性(tuple)

1 std::tuple 简介

1.1 std::tuple 概述

std::tuple 是一个固定大小的不同类型值的集合,可以看作 std::pair 的泛化,即 std::pair 是 std::tuple 的一个特例,其长度受限为 2。与 C# 中的 tuple 类似,但 std::tuple 的功能更为强大。

当需要将一些数据组合成一个单一的对象,但又不想麻烦地定义一个新的数据结构来表示这些数据时,std::tuple 是一个非常有用的工具。可以将 std::tuple 看作一个“快速而随意”的数据结构。

std::tuple 的一个重要特性是它可以存储不同类型的数据,这是它与常规 STL 容器的最大不同。例如,可以在一个 std::tuple 中同时存储一个整数、一个字符串和一个浮点数。定义 std::tuple 时,需要指出每个成员的类型,如 std::tuple<int, std::string> tu{2, “12iop”};。

访问 std::tuple 中的元素通常使用 std::get<N>() 函数,其中N是元素的索引(从0开始)。例如,如果有一个 std::tuple<int, char> my_tuple,则可以使用std::get<0>(my_tuple) 来获取第一个元素(整数),使用 std::get<1>(my_tuple) 来获取第二个元素(字符)。

1.2 std::tuple 与 std::pair 的区别

std::tuple 和 std::pair 都是 C++ 标准库中的模板类,用于将多个数据项组合成一个单一的复合数据结构。然而,它们在功能、用途以及数据项的数量上存在显著的差异:

(1)数据项数量:

  • std::pair:这是一个特殊的模板类,只能将两个不同类型的数据项绑定成一个对象。也就是说,std::pair只能存储两个元素。
  • std::tuple:相比之下,std::tuple的功能更为强大,它可以绑定任意数量的不同类型的数据项。也就是说,std::tuple的成员数量是没有限制的。

(2)命名和访问方式:

  • std::pair:它为每个元素提供了特定的名字,即 first 和 second,用于访问和操作这两个元素。这种命名方式使得 std::pair 在表示一些具有特定关系的两个数据项时(如坐标点的 x 和 y)非常直观和方便。
  • std::tuple:由于它可以包含任意数量的元素,因此不能为每个元素都提供特定的名字。相反,需要使用 std::get<N>() 函数,其中N是元素的索引(从 0 开始),来访问 std::tuple 中的元素。在 C++17 及以后的版本中,也可以使用结构化绑定(structured binding)来更方便地解包和访问 std::tuple 中的元素。

(3)使用场景:

  • std::pair:由于其只能存储两个元素,并且提供了特定的名字,它通常用于表示具有特定关系的两个数据项,如键值对、坐标点等。
  • std::tuple:由于其可以存储任意数量的元素,且元素类型可以不同,它通常用于需要将多个不同类型的数据项组合在一起的情况。此外,std::tuple 还可以作为函数返回多个值的机制,这在 std::pair 无法满足需求时尤其有用。

1.3 std::tuple 的用途与场景

以下是 std::tuple 的主要用途与场景:

(1)作为函数返回多个值:
场景:当希望一个函数返回多个值时,可以使用 std::tuple 来避免使用全局变量或指针参数传递结果。
用途:通过将多个返回值打包成一个 std::tuple 对象,可以方便地返回多个值,并在调用方进行解包。

(2)存储不同类型的数据项:
场景:当需要存储多个不同类型的数据项,但又不想定义一个新的数据结构时。
用途:std::tuple 可以存储任意数量的不同类型的数据项,提供了一种灵活的方式来组合数据。

(3)在泛型编程中传递参数:
场景:在泛型编程中,可能需要传递多个参数给某个函数或模板,而这些参数的类型可能各不相同。
用途:使用 std::tuple 可以方便地打包这些参数,并通过引用或值的方式传递给其他函数或模板。

(4)与算法结合使用:
场景:在编写算法时,可能需要处理多个不同类型的数据项。
用途:std::tuple 可以作为算法的输入或输出,使得算法能够处理不同类型的数据,并返回多个结果。

(5)替代结构体或类:
场景:当需要临时组合几个数据项,但又不想定义一个完整的结构体或类时。
用途:std::tuple 提供了一种轻量级的方式来组合数据,无需编写额外的结构体或类定义。

(6)与STL容器结合使用:
场景:在需要存储多个 std::tuple 对象的场景中,如集合、映射或向量等。
用途:std::tuple 可以作为 STL 容器的元素类型,使得容器能够存储包含多个不同类型数据项的对象。

(7)作为模板元编程的工具:
场景:在模板元编程中,std::tuple 可以用于类型列表的创建和操作。
用途:通过 std::tuple,可以方便地构建和操作类型列表,实现更复杂的类型操作和元函数。

2 std::tuple 的基本操作

2.1 std::tuple 的创建

最常见的方法是使用 std::make_tuple 函数,它接受任意数量和类型的参数,并返回一个包含这些参数的 std::tuple 对象。

例如:

#include <tuple>  
#include <iostream>  
#include <string>  int main() 
{  // 创建一个包含整数、字符串和浮点数的 tuple  std::tuple<int, std::string, double> myTuple = std::make_tuple(12, "Hello", 3.14);  // 输出 tuple 中的元素  std::cout << "Integer: " << std::get<0>(myTuple) << std::endl;  std::cout << "String: " << std::get<1>(myTuple) << std::endl;  std::cout << "Double: " << std::get<2>(myTuple) << std::endl;  return 0;  
}

这个例子创建了一个包含整数 12、字符串 “Hello” 和浮点数 3.14 的 std::tuple 对象。std::get<N>(tuple) 函数用于访问 tuple 中索引为 N 的元素,其中 N 是从 0 开始的索引。

2.2 std::tuple 的访问与修改

(1)访问 std::tuple 中的元素

访问 std::tuple 中的元素主要使用 std::get 函数。std::get 函数接受两个参数:要访问的元素的索引(从 0 开始)和 tuple 对象本身。它返回对应索引位置的元素的引用,因此你可以读取或修改该元素的值(如果元素不是常量)。

示例:

#include <tuple>  
#include <iostream>  
#include <string>  int main() 
{  std::tuple<int, std::string, double> myTuple = std::make_tuple(12, "Hello", 3.14);  // 访问 tuple 中的元素  int first = std::get<0>(myTuple);     // 获取第一个元素(整数 12)  std::string second = std::get<1>(myTuple); // 获取第二个元素(字符串 "Hello")  double third = std::get<2>(myTuple);      // 获取第三个元素(浮点数 3.14)  // 输出元素的值  std::cout << "First: " << first << std::endl;  std::cout << "Second: " << second << std::endl;  std::cout << "Third: " << third << std::endl;  return 0;  
}

上面的示例使用 std::get<N>(myTuple) 来访问 myTuple 中的每个元素,其中 N 是元素的索引。

(2)修改 std::tuple 中的元素

由于 std::get 返回的是元素的引用,因此可以直接通过它来修改 tuple 中的元素值。注意:不能改变 tuple 的大小或添加/删除元素,只能修改现有元素的值。

示例:

#include <tuple>  
#include <iostream> 
#include <string>   int main() 
{  std::tuple<int, std::string, double> myTuple = std::make_tuple(12, "Hello", 3.14);  // 修改 tuple 中的元素  std::get<0>(myTuple) = 100;             // 修改第一个元素为整数 100  std::get<1>(myTuple) = "World";         // 修改第二个元素为字符串 "World"  std::get<2>(myTuple) = 2.1;           // 修改第三个元素为浮点数 2.1  // 输出修改后的元素值  std::cout << "Modified First: " << std::get<0>(myTuple) << std::endl;  std::cout << "Modified Second: " << std::get<1>(myTuple) << std::endl;  std::cout << "Modified Third: " << std::get<2>(myTuple) << std::endl;  return 0;  
}

这个示例使用 std::get<N>(myTuple) 来获取元素的引用,并直接赋值以修改元素的值。

2.3 std::tuple 的大小与类型

std::tuple 的大小和类型在创建时就已经确定,并且在整个生命周期中保持不变。为了获取 std::tuple 的大小和类型信息,C++ 标准库提供了 std::tuple_size 和 std::tuple_element 这两个模板类。通过使用 std::tuple_size 和 std::tuple_element,可以在编译时获取 std::tuple 的大小和类型信息,这对于编写泛型代码和进行元编程非常有用。

(1)使用 std::tuple_size 获取大小

std::tuple_size 是一个模板类,它用于在编译时获取 std::tuple 的大小(即元素数量)。这个模板类接受一个 tuple 类型作为模板参数,并定义了一个名为 value 的静态成员常量,表示该 tuple 的大小。

下面是一个使用 std::tuple_size 获取 tuple 大小的示例:

#include <tuple>  
#include <iostream>  int main() 
{  std::tuple<int, double, std::string> myTuple;  // 使用 std::tuple_size 获取 tuple 的大小  constexpr std::size_t tupleSize = std::tuple_size<decltype(myTuple)>::value;  std::cout << "Tuple size: " << tupleSize << std::endl; // 输出: Tuple size: 3  return 0;  
}

这个示例创建了一个包含三个元素的 tuple(一个 int、一个 double 和一个 std::string)。然后,使用 std::tuple_size 来获取这个 tuple 的大小,并将其存储在 tupleSize 变量中。注意,std::tuple_size 是一个模板类,因此需要使用 decltype 来获取 myTuple 的类型,并将其作为模板参数传递给 std::tuple_size。最后,通过访问 std::tuple_size<decltype(myTuple)>::value 来获取 tuple 的大小。

(2)使用 std::tuple_element 获取类型

std::tuple_element 是一个模板类,它用于在编译时获取 std::tuple 中指定位置的元素的类型。这个模板类接受两个模板参数:第一个参数是元素的索引(从 0 开始),第二个参数是 tuple 的类型。它定义了一个名为 type 的嵌套类型别名,表示该索引位置的元素的类型。

下面是一个使用 std::tuple_element 获取 tuple 中元素类型的示例:

#include <tuple>  
#include <iostream>  
#include <type_traits>  int main() 
{  std::tuple<int, double, std::string> myTuple;  // 使用 std::tuple_element 获取 tuple 中指定位置元素的类型  using FirstElementType = std::tuple_element<0, decltype(myTuple)>::type;  using SecondElementType = std::tuple_element<1, decltype(myTuple)>::type;  using ThirdElementType = std::tuple_element<2, decltype(myTuple)>::type;  std::cout << "First element type: " << typeid(FirstElementType).name() << std::endl; // 输出类型名,可能是 "i" 对于 int  std::cout << "Second element type: " << typeid(SecondElementType).name() << std::endl; // 输出类型名,可能是 "d" 对于 double  std::cout << "Third element type: " << typeid(ThirdElementType).name() << std::endl; // 输出类型名,可能是与 std::string 相关的复杂类型名  return 0;  
}

这个示例使用 std::tuple_element 来获取 tuple 中每个位置的元素的类型,并将它们存储在类型别名 FirstElementType、SecondElementType 和 ThirdElementType 中。然后,使用 typeid 运算符和 name 成员函数来获取这些类型的名称,并输出它们。注意,typeid 和 name 通常用于调试目的,因为返回的类型名称可能是编译器特定的,并且可能不容易阅读。在实际编程中,通常不需要直接打印类型名称,而是依赖于类型推导和模板机制来处理 tuple 中的元素类型。

3 std::tuple 的高级特性

3.1 std::tuple 的赋值与拷贝

(1)赋值操作

std::tuple 的赋值操作可以通过使用 = 运算符来完成。可以将一个 tuple 的值赋给另一个同类型的 tuple。在赋值过程中,源 tuple 中的每个元素都会被复制到目标 tuple 中对应的位置。

下面是一个简单的示例,展示了如何进行 std::tuple 的赋值操作:

#include <tuple>  
#include <iostream>  
#include <string>   int main() 
{  // 创建并初始化第一个 tuple  std::tuple<int, double, std::string> tuple1(1, 2.0, "three");  // 创建第二个未初始化的 tuple,与 tuple1 类型相同  std::tuple<int, double, std::string> tuple2;  // 将 tuple1 的值赋给 tuple2  tuple2 = tuple1;  // 输出 tuple2 的值,应该与 tuple1 相同  std::cout << std::get<0>(tuple2) << " " << std::get<1>(tuple2) << " " << std::get<2>(tuple2) << std::endl;  // 输出:1 2 three  return 0;  
}

上面的示例首先创建了一个名为 tuple1 的 tuple 并进行了初始化。然后,创建了一个名为 tuple2 的未初始化的 tuple,它的类型与 tuple1 相同。接下来,使用赋值运算符 = 将 tuple1 的值赋给了 tuple2。最后,通过 std::get 函数输出了 tuple2 的值,可以看到它的值与 tuple1 相同。

(2)拷贝操作

std::tuple 的拷贝操作通常是在创建新的 tuple 对象时隐式进行的,即通过使用已存在的 tuple 对象来初始化新的 tuple 对象。在拷贝过程中,源 tuple 中的每个元素都会被复制到新创建的 tuple 中。

下面是一个示例,展示了如何进行 std::tuple 的拷贝操作:

#include <tuple>  
#include <iostream>  
#include <string>   int main() 
{  // 创建并初始化第一个 tuple  std::tuple<int, double, std::string> tuple1(1, 2.0, "three");  // 使用 tuple1 来初始化第二个 tuple,这是一个拷贝操作  std::tuple<int, double, std::string> tuple3(tuple1);  // 输出 tuple3 的值,应该与 tuple1 相同  std::cout << std::get<0>(tuple3) << " " << std::get<1>(tuple3) << " " << std::get<2>(tuple3) << std::endl;  // 输出:1 2 three  return 0;  
}

上面的示例通过将 tuple1 作为参数传递给 tuple3 的构造函数来创建 tuple3。这是一个拷贝操作,因为 tuple3 是通过复制 tuple1 的值来初始化的。最后,输出了 tuple3 的值,可以看到它的值与 tuple1 相同。

需要注意的是,std::tuple 的赋值和拷贝操作都是浅拷贝(shallow copy),即对于包含指针或引用等复杂类型的 tuple,只会复制指针或引用的值,而不会复制指针或引用所指向的实际数据。如果需要进行深拷贝(deep copy),即复制指针或引用所指向的实际数据,需要自己实现相应的拷贝逻辑。

3.2 std::tuple 的比较操作

std::tuple 默认不提供直接的比较操作,因为其中包含的元素类型可能不同,而且不同类型之间的比较可能没有明确定义。

但是,可以通过重载比较运算符或提供自定义的比较函数来定义 std::tuple 之间的比较逻辑。一种常见的方法是编写一个自定义的比较函数,该函数接受两个 std::tuple 作为参数,并返回一个布尔值来表示它们之间的关系(如相等、小于等)。在这个函数中,可以根据需要比较 tuple 中的每个元素。

例如,假设有一个包含两个元素的 tuple(一个 int 和一个 double),则可以这样定义比较函数:

#include <tuple>  
#include <iostream>  bool compareTuples(const std::tuple<int, double>& t1, const std::tuple<int, double>& t2) {  if (std::get<0>(t1) != std::get<0>(t2)) {  return std::get<0>(t1) < std::get<0>(t2); // 先比较第一个元素  } else {  return std::get<1>(t1) < std::get<1>(t2); // 如果第一个元素相等,则比较第二个元素  }  
}  int main() 
{  std::tuple<int, double> t1(1, 2.0);  std::tuple<int, double> t2(2, 1.0);  std::tuple<int, double> t3(1, 3.0);  std::cout << std::boolalpha; // 输出 bool 值为 true 或 false 而不是 1 或 0  std::cout << "t1 < t2: " << compareTuples(t1, t2) << std::endl; // 输出: t1 < t2: true  std::cout << "t1 < t3: " << compareTuples(t1, t3) << std::endl; // 输出: t1 < t3: true  std::cout << "t2 < t3: " << compareTuples(t2, t3) << std::endl; // 输出: t2 < t3: false  return 0;  
}

在上面的示例中,compareTuples 函数首先比较两个 tuple 的第一个元素(一个 int)。如果它们不相等,函数就返回比较结果。如果第一个元素相等,函数就继续比较第二个元素(一个 double)。这种方法允许按照所需要的顺序和逻辑来比较 tuple 中的元素。

3.3 std::tie 的使用

std::tie 是 C++ 标准库中的一个函数,它主要用于创建一个包含左值引用的 std::tuple 对象。这个函数在需要将多个变量绑定到一个元组,或者需要将一个元组解包为独立对象时特别有用。

(1)定义与用法

std::tie 的定义如下:

template<class... Types>   
tuple<Types&...> tie(Types&... args) noexcept;

这里,Types&… args 是一个模板参数包,它接受任意数量和类型的左值引用参数。std::tie 函数返回一个 std::tuple,其中包含传入参数的左值引用。

(2)使用示例

下面是一个使用 std::tie 的简单示例:

#include <iostream>  
#include <tuple>  int main() 
{  int x = 10;  int y = 20;  int z = 30;  // 使用 std::tie 将变量 x, y, z 绑定到元组中  std::tie(x, y, z) = std::make_tuple(z, x, y);  std::cout << "x: " << x << std::endl; // 输出: 30  std::cout << "y: " << y << std::endl; // 输出: 10  std::cout << "z: " << z << std::endl; // 输出: 20  return 0;  
}

这个例子首先创建了三个整数变量 x、y 和 z,并分别初始化为 10、20 和 30。然后,使用 std::tie 将这些变量绑定到一个元组中,并使用 std::make_tuple 创建了一个新的元组,其中元素的顺序为 z、x、y。通过赋值操作,实际上交换了 x、y 和 z 的值。

(3)在结构体中的使用

std::tie 也可以用于结构体的成员函数,以便返回结构体的多个成员。例如:

#include <iostream>  
#include <string>  
#include <tuple>  struct Test {  int id;  std::string name;  // ... 其他成员 ...  auto tie() const {  return std::tie(id, name /*, ... 其他成员 ... */);  }  
};  int main() 
{  Test t1{1, "Alice"};  Test t2{2, "Bob"};  if (t1.tie() == t2.tie()) {  std::cout << "t1 and t2 are equal" << std::endl;  } else {  std::cout << "t1 and t2 are not equal" << std::endl;  }  return 0;  
}

上面代码的输出为:

t1 and t2 are not equal

在这个例子中,Test 结构体有一个 tie 成员函数,它返回一个包含 id 和 name 成员的 std::tuple。然后,我们可以使用这个 tie 函数来比较两个 Test 对象的相应成员是否相等。

(4)注意事项

  • 使用 std::tie 时,必须确保绑定的变量是左值,即它们必须有明确的存储位置(不能是临时对象或右值)。
  • std::tie 创建的元组包含对原始变量的引用,因此对元组中的元素所做的任何修改都会反映到原始变量上。
  • 当不再需要 std::tie 创建的元组时,应确保不会意外地修改或销毁通过引用绑定的变量,这可能会导致悬挂引用或未定义行为。

3.4 std::ignore 在 std::tuple 中的使用

std::ignore 是 C++ 标准库中的一个特殊工具,主要用于在解包 std::tuple 或处理结构化绑定时忽略某些不需要的元素。这在处理包含多个返回值或参数的函数或数据结构时特别有用,特别是当你只对其中一部分返回值或参数感兴趣时。

(1)使用场景

当使用 std::get 从 tuple 中提取特定元素时,或者在使用结构化绑定时,可能不想处理 tuple 中的所有元素。在这些情况下,可以使用 std::ignore 来指示编译器忽略不关心的元素。

(2)示例

假设有一个返回三个值的函数,但只关心前两个值:

#include <tuple>  
#include <iostream>  std::tuple<int, double, std::string> getValues() {  return std::make_tuple(10, 20.5, "Hello");  
}  int main() 
{  auto values = getValues();  // 使用 std::ignore 忽略第三个元素  int a;  double b;  std::ignore = std::get<2>(values); // 忽略第三个元素  std::tie(a, b, std::ignore) = values; // 只提取前两个元素  std::cout << "a: " << a << ", b: " << b << std::endl;  // 输出: a: 10, b: 20.5  return 0;  
}

在上面的示例中,getValues 函数返回一个包含三个元素的 tuple。在 main 函数中,只关心前两个元素(一个 int 和一个 double)。所以使用 std::ignore 来忽略第三个元素(一个 std::string),并通过 std::tie 提取前两个元素的值。

(3)注意事项

  • std::ignore 本身是一个对象,但当将其用作绑定目标时,编译器会特殊处理它,使其忽略对应的值。
  • 当只关心 tuple 中的部分元素时,使用 std::ignore 可以使代码更清晰,避免不必要的变量声明和未使用的警告。
  • std::ignore 主要用于解包操作,不适用于其他场景,比如直接赋值或比较操作。在这些情况下,需要显式地处理所有元素。

4 使用 std::tuple 实现多返回值函数

下面是一个示例,展示了如何定义一个返回std::tuple的函数,并如何使用std::get来提取返回元组中的各个值:

#include <iostream>  
#include <tuple>  
#include <string>  // 定义一个返回std::tuple的函数  
std::tuple<int, double, std::string> get_multiple_values() {  int a = 10;  double b = 20.5;  std::string s = "Hello, tuple!";  return std::make_tuple(a, b, s);  
}  int main() 
{  // 调用函数并接收返回的元组  std::tuple<int, double, std::string> result = get_multiple_values();  // 使用std::get来访问元组中的元素  int int_value = std::get<0>(result);  double double_value = std::get<1>(result);  std::string string_value = std::get<2>(result);  // 打印解包后的值  std::cout << "Int: " << int_value << std::endl;  std::cout << "Double: " << double_value << std::endl;  std::cout << "String: " << string_value << std::endl;  return 0;  
}

上面代码的输出为:

Int: 10
Double: 20.5
String: Hello, tuple!

在这个例子中,get_multiple_values 函数返回一个包含 int、double 和 std::string 类型的 std::tuple。在 main 函数中,调用这个函数并将返回的元组存储在 result 变量中。然后,使用 std::get 函数和相应的索引来访问元组中的每个元素,并将它们分别存储在 int_value、double_value 和 string_value 变量中。最后,打印这些变量的值。

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

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

相关文章

数据库基本介绍及编译安装mysql

目录 数据库介绍 数据库类型 数据库管理系统&#xff08;DBMS&#xff09; 数据库系统 DBMS的工作模式 关系型数据库的优缺点 编译安装mysql 数据库介绍 数据&#xff1a;描述事物的的符号纪录称为数据&#xff08;Data&#xff09; 表&#xff1a;以行和列的形式组成…

mysql迁移达梦数据库 Java踩坑合集

达梦数据库踩坑合集 文章目录 安装达梦设置大小写不敏感Spring boot引入达梦驱动&#xff08;两种方式&#xff09;将jar包打入本地maven仓库使用国内maven仓库&#xff08;阿里云镜像&#xff09; 达梦驱动yml配置springboot mybatis-plus整合达梦,如何避免指定数据库名&…

CCAA审核员考试认证通用基础--合格评定基础练习题

合格评定基础练习题 一、单项选择题 1.与适用相同的规定要求、具体规则与程序的特定的合格评定对象有关的合格评定制度是&#xff08; &#xff09;。 A.合格评定 B 合格评定制度. C.合格评定方案 D.合格评定规范 2.认证也被称为&#xff08; &#xff09; A.证明 B.…

常用负载均衡详解

一、介绍 在互联网场景下&#xff0c;负载均衡&#xff08;Load Balance&#xff09;是分布式系统架构设计中必须考虑的一个环节&#xff0c;它通常是指将负载流量&#xff08;工作任务、访问请求&#xff09;平衡、分摊到多个操作单元&#xff08;服务器、组件&#xff09;上去…

Vue 计算属性和watch监听

1.1.计算属性 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><!-- 引入vue.js --><script src"node_modules/vue/dist/vue.js"></script> </h…

MySQL 快速学习路径

整理了下MySQL的快速学习路径 最近因为失业一直在家&#xff0c;闲来没事打算学习一下&#xff0c;打发时间。 大家可以订阅关注加转发 \(^o^)/~MySQL安装(Mac系统) MySQL的启停登陆与退出 MySQL的目录结构 MySQL语法分类 DDL&#xff08;1&#xff09; MySQL语法分类 DDL…

蚓链与数字化供应链的融合 带给新零售新福音

蚓链数字化生态与全境供应链的数字化融合&#xff0c;确实为新零售数字化营销带来了新的机遇。这种结合不仅提供了创新的思维和方法&#xff0c;更为新零售企业提供了强大的数字化承载和解决方案&#xff0c;使其能够更快捷地启动动销、实现倍速裂变、高福利宠粉&#xff0c;以…

如何在尽量不损害画质的前提下降低视频占内存大小?视频格式科普及无损压缩软件推荐

大家好呀&#xff0c;相比大家都有对视频画质和体积的追求和取舍&#xff0c;那么&#xff0c;如何才能在不牺牲画质的前提下&#xff0c;尽可能的将视频大小降低到极致呢&#xff1f; 首先我们要了解视频的构成&#xff0c;要想降低视频的体积大小&#xff0c;我们可以从以下几…

FITS:一个轻量级而又功能强大的时间序列分析模型

AI预测相关目录 AI预测流程&#xff0c;包括ETL、算法策略、算法模型、模型评估、可视化等相关内容 最好有基础的python算法预测经验 EEMD策略及踩坑VMD-CNN-LSTM时序预测对双向LSTM等模型添加自注意力机制K折叠交叉验证optuna超参数优化框架多任务学习-模型融合策略Transform…

MySQL 多表查询强化练习

环境准备 create table dept(id int PRIMARY KEY,dname VARCHAR(50),loc VARCHAR(50) ); insert into dept values (10,研发部,北京), (20,学工部, 上海), (30,销售部,广州 ), (40,财务部,深圳);create table job(id int PRIMARY KEY,jname VARCHAR(20),descripition VARCHAR(…

【web世界探险家】HTML5 探索与实践

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ &…

129740-002 是ABB生产的模块吗?

ABB 129740-002是一款智能模拟量输入输出IO模块。 这款模块的主要功能是进行模拟信号与数字信号之间的转换。具体来说&#xff0c;它可以将模拟信号转换为数字信号&#xff0c;也可以将数字信号转换回模拟信号。这一特性使其在工业应用中具有重要作用&#xff0c;尤其是在过程…

Cesium新版修改源码后,编译不生效问题

最新版本的cesium源码在编译时默认使用node_models下的cesium/engine&#xff0c;从而导致咱们修改项目中的源码并不会生效 解决方式 &#xff1a; 进入到实际的源码位置&#xff0c;执行npm link 在返回到源码的根目录下执行 npm link ./packages/engine

vue3 几种实现点击复制链接的方法

vue3 几种实现点击复制链接的方法 环境&#xff1a;vue3tselment plus 目的&#xff1a;常用到的地方就是点击复制分享链接功能 1.复制当前页面链接&#xff0c; <template><div class"news" style"margin-top: 30px"><el-button type&q…

C++ 函数模板

C 函数模板 函数模板 在C中&#xff0c;函数模板是一种允许函数以一种类型无关的方式来操作的工具。它们使得函数能够处理不同类型的数据而不需要为每种类型编写重复的代码。函数模板的核心思想是“参数化类型”&#xff0c;这意味着在定义函数时&#xff0c;可以使用一个或多…

Java动态SQL知识点(含面试大厂题和源码)

排序算法是数据结构与算法中的基本问题之一&#xff0c;它们的目的是将一组数据按照一定的顺序排列。不同的排序算法有着不同的时间复杂度、空间复杂度、稳定性等特性。在Java开发中&#xff0c;了解和掌握这些排序算法对于处理数据排序问题非常重要。下面是一些常用排序算法的…

游戏 AI 反作弊|内附解决方案详情!

我们提出使用在游戏中广泛存在的回放日志数据&#xff0c;重构出玩家当局的表现。在回放 日志数据中&#xff0c;我们构建了玩家的时序行为数据&#xff0c;并基于该时序行为数据&#xff0c;分别搭建 了透视和自瞄外挂检测系统&#xff0c;该方法和系统可广泛应用于各种在线…

SAP STMS请求重复传输

STMS 在接请求的导入的时候&#xff0c;第一次发生了错误&#xff0c;在修复了错误之后&#xff0c; 该请求二次导入显示已经该请求已全部导入 可以按如下操作进行再次导入 附加--》其他请求--》添加 输入请求号并勾选再次导入 然后点选需要重复导入的请求号即可再次导入

【移动端】AMap Flutter与Android AMap SDK交互

背景 本文的背景&#xff0c;是因为我在开发高德地图时&#xff0c;需要自定义高德比例尺位置和样式&#xff1b;但结果查看了AMap Flutter插件和AMap SDK源码后&#xff0c;发现AMap无法添加自定义MyMethodCallHandler的实现类&#xff01; why&#xff1f; 源码 在Flutte…

AI算力池化赋能企业大模型价值探索

1. 大语言模型企业落地中的算力痛点 随着人工智能技术的飞速发展&#xff0c;自然语言处理&#xff08;NLP&#xff09;成为了热门的研究领域之一。在这一领域中&#xff0c;大语言模型&#xff08;Large Language Models&#xff09;凭借其强大的语言理解和生成能力&#xff…