stl 相关问题

标准模板库(STL)是通用容器,迭代器,算法和函数对象的C ++库。当C ++被标准化时,STL的大部分被采用到标准库中,并且标准库中的这些部分有时也被错误地统称为“STL”。

使用 constexpr if 定义并声明 const std::array

我正在尝试实现高斯-勒让德求积,我想要一个模板化函数 将点数作为模板参数。 现在我有这个: 模板 我正在尝试实现高斯-勒让德求积,并且我想要一个模板化函数 将点数作为模板参数。 现在我有这个: template<int number_of_quadrature_points> double gaussian_quadrature_integral_core(double (*f)(double), double from, double to){ double scaling_factor = (to-from)/2; double average_factor = (from+to)/2; std::array<double, number_of_quadrature_points> factors; std::array<double, number_of_quadrature_points> points; if constexpr(number_of_quadrature_points == 2){ factors = {1, 1}; points = {-1.0/sqrt(3), 1.0/sqrt(3)}; } if constexpr(number_of_quadrature_points == 3){ factors = {5.0/9.0, 8.0/9.0, 5.0/9.0}; points = {-sqrt(3.0/5.0), 0, sqrt(3.0/5.0)}; } double sum = 0; for(int i = 0; i < number_of_quadrature_points; i++){ sum += factors.at(i)*((*f)(scaling_factor*points.at(i)+average_factor)); } sum *= scaling_factor; return sum; } 如您所见,当模板参数发生变化时,不仅数组大小发生变化,而且内容也发生变化,但对于给定的大小,内容是众所周知的。出于这个原因,我认为如果 std::arrays 是 const static 会更好,因为该函数被调用很多次。 现在我只能使用 if constexpr 来声明数组,但是如何使用它来定义和声明数组,以便它在 if constexpr 范围之外可见并且数组只定义一次? 添加两个辅助函数就足够了(如果您使用的是 C++20): template<unsigned N> constexpr auto init_factors() { std::array<double, N> rv; if constexpr(N == 2){ rv = {1., 1.}; } else { rv = {5.0/9.0, 8.0/9.0, 5.0/9.0}; } return rv; } template<unsigned N> constexpr auto init_points() { std::array<double, N> rv; if constexpr(N == 2){ rv = {-1.0/std::sqrt(3.), 1.0/std::sqrt(3.)}; } else { rv = {-std::sqrt(3.0/5.0), 0, std::sqrt(3.0/5.0)}; } return rv; } template<unsigned number_of_quadrature_points> double gaussian_quadrature_integral_core(double (*f)(double), double from, double to) { static constexpr auto factors = init_factors<number_of_quadrature_points>(); static constexpr auto points = init_points<number_of_quadrature_points>(); [...] 为了防止使用错误的点数,您可以添加 static_assert template<unsigned number_of_quadrature_points> double gaussian_quadrature_integral_core(double (*f)(double), double from, double to) { static_assert(number_of_quadrature_points==2||number_of_quadrature_points==3); ...或者如果您想稍后进行专业化,请阻止使用 SFINAE 进行匹配: #include <type_traits> template<unsigned number_of_quadrature_points> std::enable_if_t<number_of_quadrature_points==2||number_of_quadrature_points==3, double> gaussian_quadrature_integral_core(double (*f)(double), double from, double to) { 您可能有模板变量: template <std::size_t N> static constexpr std::array<double, N> factors; template <std::size_t N> static constexpr std::array<double, N> points; template <> constexpr std::array<double, 2> factors<2>{{1, 1}}; template <> constexpr std::array<double, 2> points<2>{{-1.0 / sqrt(3), 1.0 / sqrt(3)}}; template <> constexpr std::array<double, 3> factors<3>{{5.0 / 9.0, 8.0 / 9.0, 5.0 / 9.0}}; template <> constexpr std::array<double, 3> points<3>{{-sqrt(3.0 / 5.0), 0, sqrt(3.0 / 5.0)}}; 然后 template<int number_of_quadrature_points> double gaussian_quadrature_integral_core(double (*f)(double), double from, double to) { const double scaling_factor = (to - from) / 2; const double average_factor = (from + to) / 2; double sum = 0; for(int i = 0; i < number_of_quadrature_points; i++){ sum += factors<number_of_quadrature_points>[i] * ((*f)(scaling_factor * points<number_of_quadrature_points>[i] + average_factor)); } sum *= scaling_factor; return sum; } 演示 请注意,如果您没有 constexpr constexpr(而 const 没有),则必须将 sqrt 替换为 std::。 您可以使用本主题中类似的内容: 有没有办法在 C++ 模板特化中对常量值参数设置条件? 因此,我们使用 std::enable_if 和 SFINAE 创建两个模板专业化。我们通过模板参数number_of_quadrature_points来区分它们。这样我们就有了全局参数,不必多次定义和实例化。此代码使用 c++17 编译。 我还建议使用现代方法 std::function<> 而不是函数指针。 #include <array> #include <cmath> #include <iostream> #include <functional> template<int number_of_quadrature_points, typename E=void> struct gaussian_quadrature_params { }; template<int number_of_quadrature_points> struct gaussian_quadrature_params<number_of_quadrature_points, std::enable_if_t<(number_of_quadrature_points==2)> > { constexpr static const std::array<double, number_of_quadrature_points> factors = {1, 1}; constexpr static const std::array<double, number_of_quadrature_points> points = {-1.0/sqrt(3), 1.0/sqrt(3)}; }; template<int number_of_quadrature_points> struct gaussian_quadrature_params<number_of_quadrature_points, std::enable_if_t<(number_of_quadrature_points==3)> > { constexpr static const std::array<double, number_of_quadrature_points> factors = {5.0/9.0, 8.0/9.0, 5.0/9.0}; constexpr static const std::array<double, number_of_quadrature_points> points = {-sqrt(3.0/5.0), 0, sqrt(3.0/5.0)}; }; double f(double x) { return x; } template<int number_of_quadrature_points> double gaussian_quadrature_integral_core(std::function<double(double)> f, double from, double to){ double scaling_factor = (to-from)/2; double average_factor = (from+to)/2; double sum = 0; for(int i = 0; i < number_of_quadrature_points; i++){ sum += gaussian_quadrature_params<number_of_quadrature_points>::factors.at(i)*(f(scaling_factor*gaussian_quadrature_params<number_of_quadrature_points>::points.at(i)+average_factor)); } sum *= scaling_factor; return sum; } int main() { std::cout << gaussian_quadrature_integral_core<2>(f, -1.0, 1.0) << std::endl; std::cout << gaussian_quadrature_integral_core<3>(f, -1.0, 1.0) << std::endl; } 怎么样 // N: number_of_quadrature_points template<int N> double gaussian_quadrature_integral_core(double (*f)(double), double from, double to) { constexpr std::array<double, N> factors = []() ->std::array<double, N>{ if constexpr(N == 2) return {1.0, 1.0}; else if constexpr(N == 3) return {5.0 / 9.0, 8.0 / 9.0, 5.0 / 9.0}; // ... other N cases }(); constexpr std::array<double, N> points= []()->auto{ if constexpr(N == 2) return std::array<double, N>{-1.0 / std::sqrt(3), 1.0 / std::sqrt(3)}; else if constexpr(N == 3) return std::array<double, N>{-std::sqrt(3.0 / 5.0), 0, std::sqrt(3.0 / 5.0)}; // ... other N cases }(); double scaling_factor = (to - from) / 2; double average_factor = (from + to) / 2; double sum = 0; for (int i = 0; i < N; i++) sum += factors.at(i)*((*f)(scaling_factor * points.at(i) + average_factor)); sum *= scaling_factor; return sum; } 使用 if constexpr 声明和定义数组。

回答 4 投票 0

IntelliSense 引擎因具有范围的文件而崩溃

Visual Studio 2022(最新版本,17.7.7)IntelliSense 崩溃并显示以下代码。 重现步骤 将代码复制/粘贴到 IDE 更改代码,例如取消注释 std::vector

回答 1 投票 0

C++ 将向量<int>转换为向量<double>

将 std::vector intVec 转换为 std::vector doubleVec 的好干净方法是什么。或者,更一般地说,转换两个可转换类型的向量?

回答 3 投票 0

set 和比较/排序函子或 less 运算符

我的设置有问题。我不知道我做错了什么。也许你们中的某个人可以帮助我。那么让我们开始吧,我的程序的输出应该是: 伊克辛斯基·亚当、科瓦尔斯基·扬、诺瓦克·亚当、诺瓦克·J...

回答 2 投票 0

如何使用 C 风格数组分配 std::vector?

从 C 风格数组初始化 std::vector 最便宜的方法是什么? 示例:在下面的课程中,我有一个向量,但由于外部限制,数据将以 C 风格传入...

回答 6 投票 0

如何在迭代时删除向量中的元素?

我想使用擦除方法从向量中清除元素。但这里的问题是,不能保证该元素在向量中只出现一次。它可能会出现多次,并且我...

回答 7 投票 0

为什么这种类型的嵌套在 C++ 中是不可能的?

#包括 使用命名空间 std; bool cmp(对 aa, 对 bb) { 返回 (aa.第二 == bb.第二 ? aa.第一 < bb.first : aa.second > bb.

回答 1 投票 0

基于步幅(或其他操作)连续迭代更新范围

在下面的代码中,我可以创建 strode_view 来存储跨越范围的视图,以便我可以在不同的地方使用它(检查大小等)。但我必须添加一个新变量...

回答 1 投票 0

使用 C++ 中的自定义比较器对 <int, string> 对进行排序

我正在尝试在 C++ 中创建一组pair,并使用自定义比较器对其进行有效排序。我的要求是: 主要排序:根据

回答 1 投票 0

为什么将 char[256] 结构推送到 std::queue 比推送 std::string 结构慢?

我在STL队列推送中遇到了一个我不太理解的行为。 基本上,我有两个结构 结构体A { 字符串a; }; 结构体 B { 字符b[256]; }; 结构体A st1; 结构B st2; /* ...作为...

回答 5 投票 0

为什么 std::ranges::set_difference、std::ranges::set_intersection 不适用于 std::unordered_set?

我知道原因是这些算法被指定为需要排序范围作为输入,因此 unordered_set 将不起作用,但我想知道为什么没有指定这些算法来理解 unorde...

回答 1 投票 0

GCC 支持 C++20 std::format 吗?

如果没有,你知道什么编译器或版本会吗? 请参阅 cppreference/format。

回答 5 投票 0

x!=x 是实现 std::isnan() 的合法方法吗

尽管微软博客声称在我的代码中使用 std::isnan 仍然会生成对 c++ 运行时的调用,而不是内联 ucommiss。 现在我用 x!=x 检查解决了这个问题(因为性能很重要......

回答 2 投票 0

通过与不同类型的值进行自定义比较来查找 std::set 的元素

考虑以下带有自定义比较器的 std::set 玩具示例: #包括 结构体A { A() : a(cnt++) {} 常量整型; 静态 int cnt; }; int A::cnt = 0; 结构体{

回答 2 投票 0

为什么编译器告诉我类型是相等的,但不能将它们相互转换? C++

抱歉我的英语,我不是母语人士,请使用翻译来回答以下问题。 上下文:我有一个任务来实现 Scene 类和 Component 类。 Component 类是基类...

回答 1 投票 0

如何删除用户定义类的 std::vector 中的重复项?

我有一个文本编辑器列表,每当用户选择文件时就会在应用程序上呈现该列表。然而,当我开始删除列表中的元素以表明它们...

回答 1 投票 0

在 std::multiset 中,如果找到一个元素,是否有一个函数或算法可以仅删除一个样本(单一或重复)

也许这是重复的,但我没有找到任何搜索内容: 当对 std::multiset 调用擦除(value)时,所有具有找到的值的元素都将被删除。我能想到的唯一解决方案是:...

回答 11 投票 0

C++“向量”的源代码在哪里? [已关闭]

我正在尝试获取向量源代码以了解标准std或STL向量是如何实现的。 这是出于学习目的。我在哪里可以找到源代码? 甚至其他C++的源代码

回答 4 投票 0

std::remove 在传递索引时不起作用

我的测试程序的目标是擦除简单字符串向量中的单元格,如下所示。 程序失败(分段错误)。 静态无效显示(std::vector const &vec) {...

回答 3 投票 0

在c++中没有**std::fixed**的**std::set precision()**有什么作用?

如教程http://www.cplusplus.com/reference/iomanip/set precision/所示 // 设置精度示例 #include // std::cout、std::fixed #include // std::

回答 4 投票 0

© www.soinside.com 2019 - 2024. All rights reserved.