您的位置:首页 > 财经 > 产业 > 奖状制作app_cfa一级看多久_营销策略有哪几种_seo怎么做推广

奖状制作app_cfa一级看多久_营销策略有哪几种_seo怎么做推广

2024/12/31 5:29:43 来源:https://blog.csdn.net/charlie114514191/article/details/144658493  浏览:    关键词:奖状制作app_cfa一级看多久_营销策略有哪几种_seo怎么做推广
奖状制作app_cfa一级看多久_营销策略有哪几种_seo怎么做推广

目录

std::optional

std::any

处理我们的时间


std::optional

下面来介绍一下我们的std::optional这个类,std::optional 是 C++17 引入的一个标准库类型,它是一个轻量级的容器,能够表示一个可能没有值的对象。std::optional 用于表示某个值可能存在也可能不存在的情况,它允许我们避免使用特殊的值(如 nullptr-1)来表示缺失的值,提供了更安全、清晰的代码结构。

struct factor_t {bool is_prime;long factor;
};
​
factor_t factor(long n) {factor_t r{};for(long i = 2; i <= n / 2; ++i) {if (n % i == 0) {r.is_prime = false;r.factor = i;return r;}}r.is_prime = true;return r;
}

比如说,我们想要生成一个有特殊含义的值,为了表达它是否有效,一个经典的做法要么是返回一个非法值(类似于-1),要么就是返回一个结构体存储其是否有效(但是受困于其信息存在潜在的不同步性)

这个玩意就是解决这类问题的:

  1. 函数返回值:当函数可能无法返回有效值时,std::optional 是一个非常合适的返回类型。它避免了使用指针(例如 nullptr)或错误代码来表示失败状态。

  2. 存储可选值:在数据结构中,某些字段可能是可选的,使用 optional 可以简洁明了地表示这种情况。

  3. 避免使用特殊标记值:例如,用 -1NULL 表示一个缺失的整数值时,可能会与有效值发生冲突。std::optional 可以避免这种情况。

std::optional 可以通过两种方式创建:

  • 通过值初始化:std::optional<int> opt(10);

  • 通过无参构造:std::optional<int> opt;(表示“空”的 optional

#include <iostream>
#include <optional>
​
int main() {std::optional<int> opt1(42);  // 包含值 42std::optional<int> opt2;       // 不包含值,默认构造为空
​if (opt1) {std::cout << "opt1 has value: " << *opt1 << std::endl;}
​if (!opt2) {std::cout << "opt2 does not have value" << std::endl;}
​return 0;
}

输出:

opt1 has value: 42
opt2 does not have value

可以通过 has_value()operator bool() 来检查 optional 是否包含值。如果 optional 包含值,has_value() 返回 true,否则返回 falseoperator bool() 返回 true 表示包含值,false 表示没有值。

#include <iostream>
#include <optional>
​
int main() {std::optional<int> opt1(42);std::optional<int> opt2;
​if (opt1.has_value()) {std::cout << "opt1 has value: " << *opt1 << std::endl;}
​if (!opt2) {std::cout << "opt2 does not have value" << std::endl;}
​return 0;
}

访问 optional 中的值可以通过解引用(*)或 value() 成员函数。需要注意的是,如果 optional 中没有值,直接解引用会导致未定义行为,因此应先检查值是否存在。

#include <iostream>
#include <optional>
​
int main() {std::optional<int> opt1(42);std::optional<int> opt2;
​if (opt1) {std::cout << "opt1 contains: " << *opt1 << std::endl;  // 解引用}
​if (!opt2) {std::cout << "opt2 is empty" << std::endl;}
​return 0;
}

std::optional 提供了 value_or() 函数,可以为缺失的值提供一个默认值。

#include <iostream>
#include <optional>
​
int main() {std::optional<int> opt1(42);std::optional<int> opt2;
​std::cout << "opt1 value: " << opt1.value_or(0) << std::endl;  // 42std::cout << "opt2 value: " << opt2.value_or(0) << std::endl;  // 0
​return 0;
}

输出:

opt1 value: 42
opt2 value: 0

std::optional 常用于表示函数的返回值,尤其是在函数可能无法成功返回时。例如,查找操作可能找不到目标值,此时可以返回一个空的 optional

#include <iostream>
#include <optional>
#include <vector>
​
std::optional<int> find_index(const std::vector<int>& vec, int target) {for (int i = 0; i < vec.size(); ++i) {if (vec[i] == target) {return i;  // 找到目标,返回索引}}return std::nullopt;  // 未找到目标,返回空的 optional
}
​
int main() {std::vector<int> vec = {1, 2, 3, 4, 5};
​auto index = find_index(vec, 3);if (index) {std::cout << "Found 3 at index: " << *index << std::endl;} else {std::cout << "3 not found!" << std::endl;}
​auto missing = find_index(vec, 10);if (!missing) {std::cout << "10 not found!" << std::endl;}
​return 0;
}

输出:

Found 3 at index: 2
10 not found!

std::any

刚刚我们擦除的是类型的值,现在我们关心一下,可不可以存储任意类型呢?答案是可以的,std::any 是 C++17 引入的一个标准库类型,用于存储任何类型的单一值。它是一个类型安全的容器,允许在运行时动态地存储任意类型的数据,并且能够在需要时访问这些数据。与 std::variantstd::optional 不同,std::any 允许存储任何类型,而无需在编译时确定类型。

std::any 是一个类模板,用于存储任何类型的对象。在存储值时,std::any 会自动进行类型擦除,即它会存储值的类型信息,并使得我们能够稍后重新获取该值。std::any 提供了一些常用的操作,包括:

  1. 存储值:将一个值存储到 std::any 容器中。

  2. 访问值:可以通过 std::any_cast 来访问存储的值。

  3. 检查类型std::any 提供了 has_value() 方法,可以检查是否存储了值。

std::any 主要用于以下场景:

  1. 存储不同类型的数据:当我们需要存储多种不同类型的数据时,std::any 提供了一个统一的容器,可以不关心具体类型。

  2. 类型擦除:在某些情况下,我们需要存储不同类型的对象,而又不希望每种类型都有自己的容器,这时可以使用 std::any

  3. 与反射相关的操作std::any 提供了一种方式,可以动态地操作不同类型的值,类似于反射。

std::any 可以通过构造函数来初始化并存储任何类型的值。可以直接存储类型,也可以通过 std::make_any 工具函数来构造 std::any 对象。

#include <iostream>
#include <any>
​
int main() {std::any a1 = 42;               // 存储一个 int 值std::any a2 = std::string("hello");  // 存储一个 string 值
​std::cout << "Stored an int and a string." << std::endl;
​return 0;
}

std::any 提供了 has_value() 方法来检查是否存储了一个有效的值。如果 std::any 存储了一个值,has_value() 返回 true,否则返回 false

#include <iostream>
#include <any>
​
int main() {std::any a1;  // 未初始化的 any 对象
​if (!a1.has_value()) {std::cout << "a1 does not contain a value." << std::endl;}
​a1 = 42;  // 给 any 赋一个 int 值
​if (a1.has_value()) {std::cout << "a1 contains a value." << std::endl;}
​return 0;
}

访问 std::any 中存储的值需要使用 std::any_cast。如果类型匹配,std::any_cast 会返回对应类型的引用或指针;如果类型不匹配,std::any_cast 会抛出 std::bad_any_cast 异常。

#include <iostream>
#include <any>
#include <string>
#include <exception>
​
int main() {std::any a = 42;  // 存储一个 int 类型的值
​try {int val = std::any_cast<int>(a);  // 正确:类型匹配std::cout << "Stored value: " << val << std::endl;// 错误:类型不匹配std::string str = std::any_cast<std::string>(a);  } catch (const std::bad_any_cast& e) {std::cout << "Failed to cast: " << e.what() << std::endl;}
​return 0;
}

输出:

Stored value: 42
Failed to cast: bad any cast

std::any 允许在同一个容器中存储不同类型的值。这使得它非常适合存储不确定类型的数据。例如,在某些情况下,程序可能需要处理不同类型的数据并统一存储。

#include <iostream>
#include <any>
#include <string>
​
void print_value(const std::any& a) {try {if (a.type() == typeid(int)) {std::cout << "Integer: " << std::any_cast<int>(a) << std::endl;} else if (a.type() == typeid(std::string)) {std::cout << "String: " << std::any_cast<std::string>(a) << std::endl;} else {std::cout << "Unknown type" << std::endl;}} catch (const std::bad_any_cast& e) {std::cout << "Error: " << e.what() << std::endl;}
}
​
int main() {std::any a1 = 42;               // 存储 intstd::any a2 = std::string("hello");  // 存储 string
​print_value(a1);  // 输出:Integer: 42print_value(a2);  // 输出:String: hello
​return 0;
}

std::anystd::variant 都用于存储多种类型的数据,但它们的使用场景有所不同:

  • std::any 是完全类型擦除的,它允许存储任何类型的对象,无需在编译时指定类型。但是,它的访问需要使用 std::any_cast,并且在运行时进行类型检查。

  • std::variant 是一个类型安全的联合体,它必须在编译时指定所有可能的类型。访问时通过 std::getstd::visit 来安全地获取存储的值,std::variant 在访问时提供了编译时类型检查。

#include <iostream>
#include <variant>
#include <string>
​
using VariantType = std::variant<int, std::string>;
​
int main() {VariantType v1 = 42;VariantType v2 = std::string("hello");
​std::cout << "v1 contains: " << std::get<int>(v1) << std::endl;std::cout << "v2 contains: " << std::get<std::string>(v2) << std::endl;
​return 0;
}

std::any 相比,std::variant 的类型是固定的,可以在编译时确保类型安全,而 std::any 更灵活,但也需要在运行时进行类型检查。

std::any 不仅可以存储基本数据类型,还可以存储自定义类型。为了访问存储的自定义类型,我们同样使用 std::any_cast,并确保类型匹配。

#include <iostream>
#include <any>
​
class MyClass {
public:void hello() { std::cout << "Hello from MyClass!" << std::endl; }
};
​
int main() {MyClass obj;std::any a = obj;  // 存储自定义类型
​try {MyClass& ref = std::any_cast<MyClass&>(a);  // 访问存储的 MyClass 对象ref.hello();  // 输出:Hello from MyClass!} catch (const std::bad_any_cast& e) {std::cout << "Error: " << e.what() << std::endl;}
​return 0;
}

处理我们的时间

std::chrono 是 C++11 引入的一个用于处理时间和时间间隔的库,它提供了一些类和工具来处理时间点、时间段、时钟等。下面是 std::chrono 中一些常见的类及其使用方法:

时钟类用于获取当前时间点。常见的时钟有:

  • std::chrono::system_clock

    • 这是与系统时间相关的时钟。它通常用于获取当前的时间戳。

    • 它的时间表示的是从某个特定的纪元(通常是 1970 年 1 月 1 日 UTC)到当前的时间点。

    示例:

    #include <iostream>
    #include <chrono>
    ​
    int main() {auto now = std::chrono::system_clock::now();auto duration = now.time_since_epoch(); // 获取自纪元以来的时间auto seconds = std::chrono::duration_cast<std::chrono::seconds>(duration);std::cout << "Seconds since epoch: " << seconds.count() << std::endl;return 0;
    }
  • std::chrono::steady_clock

    • 该时钟与系统时间无关,保证其每次获取的时间点之间的间隔是恒定的(即没有跳跃)。

    • 适用于测量程序运行时间和间隔。

    示例:

    #include <iostream>
    #include <chrono>
    ​
    int main() {auto start = std::chrono::steady_clock::now();// 执行一些操作auto end = std::chrono::steady_clock::now();auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);std::cout << "Elapsed time: " << duration.count() << " milliseconds" << std::endl;return 0;
    }
  • std::chrono::high_resolution_clock

    • 这是精度最高的时钟,通常作为 steady_clock 的实现。它的分辨率取决于系统。

时间点表示某一特定的时刻,通常由时钟与其起始点结合定义。时间点通过 std::chrono::time_point 表示。

  • 获取时间点:

    auto now = std::chrono::system_clock::now();
  • 转换为其他单位:

    auto seconds = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch());

std::chrono::duration 表示时间间隔,是对两个时间点之差的描述。它通常通过一个整数和一个单位(如秒、毫秒、微秒等)表示。

常见的时间间隔类:

  • std::chrono::duration<int>:表示整数类型的时间间隔。

  • std::chrono::duration<float>:表示浮动类型的时间间隔。

常见的时间单位:

  • std::chrono::seconds:表示秒。

  • std::chrono::milliseconds:表示毫秒。

  • std::chrono::microseconds:表示微秒。

  • std::chrono::nanoseconds:表示纳秒。

示例:

#include <iostream>
#include <chrono>
​
int main() {std::chrono::duration<int> d1(5);  // 5 秒std::chrono::duration<double> d2(3.14);  // 3.14 秒
​std::cout << "Duration 1: " << d1.count() << " seconds" << std::endl;std::cout << "Duration 2: " << d2.count() << " seconds" << std::endl;
​// 转换时间单位auto d1_in_ms = std::chrono::duration_cast<std::chrono::milliseconds>(d1);std::cout << "Duration 1 in milliseconds: " << d1_in_ms.count() << " ms" << std::endl;return 0;
}

std::chrono::duration_cast 用于在不同的时间单位之间进行转换。注意,转换时会丢失一些精度。

示例:

#include <iostream>
#include <chrono>
​
int main() {std::chrono::milliseconds ms(1500);  // 1500毫秒std::chrono::seconds sec = std::chrono::duration_cast<std::chrono::seconds>(ms);  // 转换为秒std::cout << sec.count() << " seconds" << std::endl;  // 输出1秒
​return 0;
}

std::chrono 可以与定时器结合使用,提供程序执行过程中的延时和超时功能。

示例:

#include <iostream>
#include <chrono>
#include <thread>
​
int main() {std::cout << "Start waiting..." << std::endl;std::this_thread::sleep_for(std::chrono::seconds(2));  // 程序暂停2秒std::cout << "Waited for 2 seconds" << std::endl;return 0;
}

你可以定义自己的时间单位,例如 1 毫秒等价于 1000 微秒。

using namespace std::chrono;
using milliseconds = duration<int, std::milli>;  // 定义1毫秒
​
int main() {milliseconds ms(500);  // 500毫秒std::cout << ms.count() << " milliseconds" << std::endl;  // 输出500return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com