小编too*_*zzy的帖子

std :: string移动构造函数实际上是移动的吗?

所以这里有一个小测试程序:

#include <string>
#include <iostream>
#include <memory>
#include <vector>

class Test
{
public:
  Test(const std::vector<int>& a_, const std::string& b_)
    : a(std::move(a_)),
      b(std::move(b_)),
      vBufAddr(reinterpret_cast<long long>(a.data())),
      sBufAddr(reinterpret_cast<long long>(b.data()))
  {}

  Test(Test&& mv)
    : a(std::move(mv.a)),
      b(std::move(mv.b)),
      vBufAddr(reinterpret_cast<long long>(a.data())),
      sBufAddr(reinterpret_cast<long long>(b.data()))
  {}

  bool operator==(const Test& cmp)
  {
    if (vBufAddr != cmp.vBufAddr) {
      std::cout << "Vector buffers differ: " << std::endl
        << "Ours: " << std::hex << vBufAddr << std::endl
        << "Theirs: " << cmp.vBufAddr << std::endl;
      return false;
    }

    if (sBufAddr != cmp.sBufAddr) {
      std::cout …
Run Code Online (Sandbox Code Playgroud)

c++ move stdstring move-semantics c++11

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

std :: initializer_list构造函数

在这样的代码中:

#include <iostream> 
#include <initializer_list>
#include <string>

struct A 
{
  A() { std::cout << "2" << std::endl; }
  A(int a) { std::cout << "0" << std::endl; }
  A(std::initializer_list<std::string> s) { std::cout << "3" << std::endl; }
  A(std::initializer_list<int> l) { std::cout << "1" << std::endl; } 
};

int main() 
{ 
 A a1{{}}; 
} 
Run Code Online (Sandbox Code Playgroud)

为什么调用std::initializer_list<int>构造函数的规范?如果我们定义构造函数,它会产生歧义编译错误std::initializer_list<double>.这种结构的规则是什么?为什么std::initializer_list数字作为模板参数如此具体?

c++ object-construction c++11 stdinitializerlist

12
推荐指数
2
解决办法
2030
查看次数

GCC 和 MSVC 中的 C++ utf-8 文字

这里我有一些简单的代码:

#include <iostream>
#include <cstdint>

    int main()
    {
         const unsigned char utf8_string[] = u8"\xA0";
         std::cout << std::hex << "Size: " << sizeof(utf8_string) << std::endl;
          for (int i=0; i < sizeof(utf8_string); i++) {
            std::cout << std::hex << (uint16_t)utf8_string[i] << std::endl;
          }
    }
Run Code Online (Sandbox Code Playgroud)

我在这里看到 MSVC 和 GCC 的不同行为。MSVC 认为"\xA0"未编码的 unicode 序列,并将其编码为 utf-8。所以在 MSVC 中,输出是:

C2A0

这是在 utf8 unicode 符号中正确编码的U+00A0

但是在 GCC 的情况下,什么也没有发生。它将字符串视为简单的字节。即使我u8在字符串文字之前删除也没有变化。

这两种编译器编码与输出UTF8C2A0如果字符串设定为:u8"\u00A0";

为什么编译器的行为不同,哪个实际上是正确的?

用于测试的软件:

海湾合作委员会 8.3.0

MSVC 19.00.23506

C++ 11

c++ unicode gcc utf-8 visual-c++

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

使用虚拟函数移动语义的最佳实践是什么?

假设我有界面:

class MyInterface
{
public:
    virtual ~MyInterface() = default;
    virtual void DoSomething(const MyType& a, const MyTypeB& b);
};
Run Code Online (Sandbox Code Playgroud)

我想要的是如果任何函数参数是右值左值引用,则允许使用移动语义。

我不想要的是像这样定义接口:

class MyInterface
{
public:
    virtual ~MyInterface() = default;
    virtual void DoSomething(const MyType& a, const MyTypeB& b);
    virtual void DoSomething(MyType&& a, const MyTypeB& b);
    virtual void DoSomething(const MyType& a, MyTypeB&& b);
    virtual void DoSomething(MyType&& a, MyTypeB&& b);
};
Run Code Online (Sandbox Code Playgroud)

如果向方法中添加更多参数,组合数学会变得更糟。

因此,在实现中,如果我传递了右值,我基本上想移动参数,否则进行复制。

标准库中有std::forward,但它与所谓的“转发引用”一起使用,这需要模板,并且在虚拟方法中不可能有模板参数。

有没有什么方法可以做到这一点,同时保留接口基类型的目的,并且不会使接口本身变得如此膨胀?

c++ interface move

6
推荐指数
0
解决办法
150
查看次数

为什么memset在calloc之后调用?

我已经研究了一些库的代码,并注意到那里的调用calloc后面跟着memset分配的块calloc.我发现这个问题有一个非常全面的答案,关于callocmalloc+ 之间的差异,并在分配存储之前memset调用memset:

为什么malloc + memset比calloc慢?

我仍然无法理解的是为什么人们会这样做.这项业务有什么好处?

上面提到的代码示例库:

light_pcapng_file_info *light_create_default_file_info()
{
    light_pcapng_file_info *default_file_info = calloc(1, sizeof(light_pcapng_file_info));
    memset(default_file_info, 0, sizeof(light_pcapng_file_info));
    default_file_info->major_version = 1;
    return default_file_info;
}
Run Code Online (Sandbox Code Playgroud)

分配结构的代码(每个数组包含32个元素):

typedef struct _light_pcapng_file_info {
    uint16_t major_version;
    uint16_t minor_version;
    char *file_comment;
    size_t file_comment_size;
    char *hardware_desc;
    size_t hardware_desc_size;
    char *os_desc;
    size_t os_desc_size;
    char *user_app_desc;
    size_t user_app_desc_size;
    size_t interface_block_count;
    uint16_t link_types[MAX_SUPPORTED_INTERFACE_BLOCKS];
    double timestamp_resolution[MAX_SUPPORTED_INTERFACE_BLOCKS];

} light_pcapng_file_info;
Run Code Online (Sandbox Code Playgroud)

编辑:

除了接受的答案,我想提供一些我的同事指出的信息.glibc中有一个错误,有时会阻止calloc将内存清零.这是链接:https: //bugzilla.redhat.com/show_bug.cgi?id = 1293976

案例链接移动时的实际错误报告文本:

glibc:calloc()返回非零内存 …

c malloc memset calloc

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

C++拷贝,移动构造函数

我这里有代码:

#include <string>
#include <iostream>
#include <initializer_list>

template <typename T>
class Test
{
public:
  Test(std::initializer_list<T> l)
  {
    std::cout << __PRETTY_FUNCTION__ << std::endl;
  }

  Test(const Test<T>& copy)
  {
    std::cout << __PRETTY_FUNCTION__ << std::endl;
  }
  Test(Test&&) = delete;
  Test() = delete;
};

void f(const Test<Test<std::string>>& x)
{
  std::cout << __PRETTY_FUNCTION__ << std::endl;
}

void f(const Test<std::string>& x)
{
  std::cout << __PRETTY_FUNCTION__ << std::endl;
  f(Test<Test<std::string>>{x});
}

int main()
{
  Test<std::string> t1 {"lol"};
  f(t1);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我尝试用我的linux mint 19上的GCC 7.3.0编译这个命令:

g ++ -std …

c++ copy-constructor move-constructor c++11

3
推荐指数
2
解决办法
1476
查看次数

堆栈上的数组内存分配

我在 C 中有 2 个函数:

void func1(unsigned char x)
{
    unsigned char a[10][5];

    a[0][0] = 1;
    a[9][4] = 2;
}

void func2(unsigned char x)
{
    unsigned char a[10][5];

    a[0][0] = 1;
    a[9][4] = 2;

    unsigned char b[10];

    b[0] = 4;
    b[9] = 5;
}
Run Code Online (Sandbox Code Playgroud)

编译:

gcc 7.3 x86-64

-O0 -g

操作系统:

16.04.1-Ubuntu x86-64

生产的英特尔功能组装:

func1(unsigned char):
  pushq %rbp
  movq %rsp, %rbp
  movl %edi, %eax
  movb %al, -68(%rbp)
  movb $1, -64(%rbp)
  movb $2, -15(%rbp)
  nop
  popq %rbp
  ret

func2(unsigned char):
  pushq …
Run Code Online (Sandbox Code Playgroud)

c memory arrays assembly stack-memory

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

unique_ptr中原始指针的默认删除器

使用默认删除器是否安全std::unique_ptr

我想这样使用它:

uint8_t* binaryData = new uint8_t[binaryDataSize];
std::unique_ptr<uint8_t> binPtr(binaryData);
Run Code Online (Sandbox Code Playgroud)

所以默认的删除器std::unique_ptr看起来像这样:

template<typename _Up>
typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type
operator()(_Up* __ptr) const
{
    static_assert(sizeof(_Tp)>0,
                  "can't delete pointer to incomplete type");
    delete [] __ptr;
}
Run Code Online (Sandbox Code Playgroud)

从我的观点来看,使用由原始指针分配的原始指针是new[]安全的,而不是由分配的原始指针安全std::malloc.我错过了什么吗?有更好的解决方案吗?

c++ malloc unique-ptr c++11

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