简体   繁体   English

C ++中静态声明的结构的范围是什么

[英]What is the scope of a statically declared struct in c++

So it's been a while since I did anything with c++ so please help me out on this issue. 自从我用c ++做任何事情以来已经有一段时间了,所以请帮助我解决这个问题。

I have a struct that I declare in a scope and then put in a map. 我有一个在作用域中声明的结构,然后放入映射中。 How come this instance is still there outside of the scope. 为什么这个实例仍然不在范围之内。 Shouldn't the allocated instance be deallocated? 分配的实例不应该被释放吗?

#include <iostream>
#include <map>
#include <iterator>

struct foo {
  int key;
  int val;
};

int main() {
  std::map<int,foo> map;
  for (int i=0; i<10; i++) {
    foo f; // allocated 1 time only?
    f.key = 1000 + i;
    if (i%2==0) {
      f.val = i;
    }
    map.insert(std::make_pair(i, f)); // f is copied into the pair?
  }

  for (std::map<int, foo>::iterator it = map.begin(); it != map.end(); ++it) {
    std::cout << it->first;
    std::cout << " :: ";
    std::cout << it->second.key;
    std::cout << " -> ";
    std::cout << it->second.val;
    std::cout << std::endl;
  }
}

this will generate the following 这将产生以下内容

0 :: 1000 -> 0
1 :: 1001 -> 0
2 :: 1002 -> 2
3 :: 1003 -> 2
4 :: 1004 -> 4
5 :: 1005 -> 4
6 :: 1006 -> 6
7 :: 1007 -> 6
8 :: 1008 -> 8
9 :: 1009 -> 8

Is the comments in the code correct? 代码中的注释正确吗?

Now, say I would like to only instanciate val every other time, and the even times i would like it to be 0 (default). 现在,假设我只想每隔一次实例化一次val,偶数次我希望它为0(默认值)。 What would be the safest and most efficient way of doing this? 这样做最安全,最有效的方法是什么?

Containers hold copies of the values, and these copies will have the same lifetime as the container. 容器保存值的副本,这些副本的寿命与容器相同。 This is called 'value-semantics', and is a key component of C++ 这称为“价值语义”,是C ++的关键组成部分

#include <iostream>
#include <vector>

struct SomeType {
    int val;
};

int main()
{
    using namespace std;

    {
        int a = 3;
        int b = a;
        a = 4;
        cout << b << endl; // this prints 3, int is a value type
    }

    {
        SomeType a = {3};
        SomeType b = a;
        a.val = 4;
        cout << b.val << endl; // this prints 3, SomeType is a value type
    }

    {
        vector<int> a = {3};
        vector<int> b = a;
        a[0] = 4;
        cout << b[0] << endl; // this prints 3, vector is a value type
    }
}

As you can see, C++ follows value-semantics (almost) everywhere. 如您所见,C ++在几乎所有地方都遵循价值语义学。 The only exceptions are thing like std::shared_ptr , which are designed to use reference/pointer semantics instead. 唯一的例外是std::shared_ptr类的东西,它们被设计为使用引用/指针语义。

In general, when designing types in C++, do what int s do. 通常,在C ++中设计类型时,请执行int的操作。

Regarding your updated question, foo is default-constructed 10 times (in the for loops body), copy constructed ten times (while creating pairs), lastly move-constructed ten times (while inserted into the container). 关于您更新的问题, foo是默认构造的10次(在for循环主体中),copy构造的是10次(在创建对时),最后是移动构造的10次(在插入到容器中时)。

Your code fails to initialize foo::val half of the time. 您的代码有一半时间无法初始化foo::val

When I compile it on https://coliru.stacked-crooked.com/ 当我在https://coliru.stacked-crooked.com/上进行编译时
I get: 我得到:

main.cpp: In function 'int main()':   main.cpp:18:35: error:
'f.foo::val' may be used uninitialized in this function [-Werror=maybe-uninitialized]
     map.insert(std::make_pair(i, f)); // f is copied into the pair?

(compiled with std=c++17 -O2 -Wall -Wextra -Werror -pedantic) (与std = c ++ 17 -O2 -Wall -Wextra -Werror -pedantic编译)

Failing to initialize a variable, and still reading it is UB (Undefined Behavior), so anything can happen; 无法初始化变量,但仍无法读取它是UB(未定义行为),因此任何事情都会发生;

To get the output you requested, and fewer copies, try: 要获得所需的输出并减少副本,请尝试:

#include <iostream>
#include <map>

struct foo {
    int key;
    int val;
};

int main() {
    std::map<int,foo> map;
    int val = 0;
    for (int i=0; i<10; i++) {
        int key = 1000 + i;
        if (i%2==0)
            val = i; // not doubled
        map.emplace(i, foo{key, val});
    }

    for (auto&& item : map) {
        std::cout << item.first << " :: " << item.second.key;
        std::cout << " -> " << item.second.val << std::endl;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM