小编Pap*_*ter的帖子

具有模板化成员函数的类,是同一类?

我对模板化的成员函数有点困惑,让我们假设我们有一些带有模板化成员函数的奇怪结构,如下所示:

struct Foo
{
    template <typename T> void f(T t) {};
};
Run Code Online (Sandbox Code Playgroud)

然后,我们将该结构存储到一些标准容器中:

std::vector<Foo> V;

V.push_back(Foo());
V.push_back(Foo());
V.push_back(Foo());
V.push_back(Foo());
Run Code Online (Sandbox Code Playgroud)

下一个; 让我们调用模板化成员函数的不同实例:

V.at(0).f<int>(1);
V.at(0).f<char>(2);
V.at(1).f<float>(3.4f);
V.at(2).f<double>(5.6);
V.at(3).f<long>(7);
Run Code Online (Sandbox Code Playgroud)

最后,问题是:

¿Foo类的所有实例都来自同一个类?似乎答案是肯定的但是......第一个Foo实例最后有两个f成员函数的重载:

[0] Foo::f(int t);
[0] Foo::f(char t);
Run Code Online (Sandbox Code Playgroud)

而另一方面,其他Foo实例似乎只有一个版本的f函数.因此,由于成员函数的差异,每个实例的基本类型显然是不同的.

[1] Foo::f(float t);
[2] Foo::f(double t);
[3] Foo::f(long t);
Run Code Online (Sandbox Code Playgroud)

¿f函数在哪里实例化?显然我们只能从第一个Foo实例获取Foo :: f(int t)函数的地址,因为该函数只属于该实例; 其他功能相同.

提前致谢.

c++ templates

2
推荐指数
1
解决办法
143
查看次数

foreach Dictionary&lt;&gt;.Values 或 foreach Dictionary&lt;&gt;

我想知道DictionaryC#中这两种迭代集合样式的细节:

Dictionary<X, Y> xydic = new Dictionary<X, Y>();
Run Code Online (Sandbox Code Playgroud)

款式一:

foreach (Y y in xydic.Values) { use y }
Run Code Online (Sandbox Code Playgroud)

款式二:

foreach (var it in xydic) { Y y = it.Value; use y... }
Run Code Online (Sandbox Code Playgroud)

我多年来一直是 C++ 开发人员(现在我在一个 C# 项目中工作),但我不知道Dictionary集合如何工作、内存布局或元素如何迭代的细节,所以我想知道:

xydic.Values创建一个临时List<Y>? 我在文档中没有看到有关创建临时列表的任何信息。

如果创建了一个临时列表,这是否意味着该集合被迭代两次:第一次创建List<Y>,第二次迭代列表本身?

如果上述问题的答案是肯定的,那么第二种风格应该更有效,使第一种风格几乎无用,所以我认为我在某种程度上应该是错误的。

我觉得这个问题应该在某个地方得到回答,但我找不到答案。

c# iteration foreach containers

2
推荐指数
1
解决办法
2662
查看次数

如何在始终选择第一个元素并过滤其余元素的范围内创建视图?

我有一个价值观的集合:

auto v = std::vector{43, 1, 3, 2, 4, 6, 7, 8, 19, 101};
Run Code Online (Sandbox Code Playgroud)

我想在这个值集合上应用遵循以下条件的视图:

  • 应始终选择第一个元素。
  • 从下一个元素中,仅选择偶数,直到...
  • ...查找等于或大于 6 的元素。

这是我尝试过的视图:

auto v = std::vector{43, 1, 3, 2, 4, 6, 7, 8, 19, 101};
auto r = v |
    std::views::take(1) |
    std::views::filter([](const int x) { return !(x & 1); }) |
    std::views::take_while([](const int x) { return x < 6; });

for (const auto &x : r)
    std::cout << x << ' ';
Run Code Online (Sandbox Code Playgroud)

但执行甚至没有进入打印循环,因为视图是空的。我的猜测是所有标准都会立即应用:

  1. 选择第一个元素 (43)。
  2. 是奇数。
  3. 观看结束。

我所期待的:

  1. 选择第一个元素而不检查任何内容。
  2. 从其余元素中,仅过滤偶数 …

c++ c++20 std-ranges

2
推荐指数
1
解决办法
936
查看次数

为什么 C++ 默认初始化不会对非类类型成员进行零初始化

为什么标准决定在默认初始化期间不对非类类型成员执行任何操作,但在值初始化期间执行初始化

如果总是对非类类型成员执行零初始化会更安全吗?

c++ initialization

1
推荐指数
1
解决办法
1790
查看次数

std :: get_temporary_buffer返回原始指针而不是智能指针

std::get_temporary_buffer回报std::pair持有的指针分配存储的开始和分配对象的数目,以及其对应的唯一的目的:std::return_temporary_buffer是为了释放内存之前与分配std::get_temporary_buffer.

这两个函数都位于<memory>标题上,其主要目的是提供增强内存管理的工具(顾名思义)并使内存管理更安全.

关于内存管理的安全性,<memory>头部还提供了智能指针实用程序,它允许以类似RAII的方式管理内存,从而使内存管理异常安全.

C++ 14还添加了std::make_unique辅助函数,因此我们现在可以避免在许多情况下使用原始指针.

通过所有这些努力减少原始指针的使用,实现std::get_temporary_buffer返回原始指针而不是智能指针是非常令人困惑的.这就是为什么我想问:

  • 是否有理由std::get_temporary_buffer返回原始指针而不是返回智能指针?
  • 如果有这种" 老式 "方式手动分配和释放内存的原因,那么智能指针无法实现哪些目标呢?

c++ memory-management c++11

0
推荐指数
1
解决办法
99
查看次数