小编cur*_*guy的帖子

对于 CPU 无法原子操作的类型, std::atomic 有什么意义?

使用std::atomic而不是互斥锁的全部意义在于:

  1. 更高的多线程代码性能(阅读器之间没有争用);
  2. 发生严重争用时的性能变化较小(重试失败的 RMW 不如失去剩余时间片那么剧烈,因为持有互斥锁的线程已准备好运行但未运行);
  3. 与信号处理程序通信的能力。

当使用互斥表“模拟”操作的原子性时:

  1. 对于只需要一个修改操作的情况,性能充其量与用户互斥锁一样好;当多个操作顺序使用时,将需要进行多次加锁/解锁操作,从而降低代码效率。
  2. 性能将不会比使用显式用户互斥锁更可预测。
  3. 这种“模拟”原子性不能与阻塞其他代码(例如信号处理程序)的代码一起使用。

那么为什么对原子 CPU 操作的这种糟糕的模拟值得呢?中非无锁回退机制的用例是std::atomic什么?

c++ multithreading mutex lock-free stdatomic

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

为什么为派生类定义复制构造函数需要定义基类的默认构造函数?

我在单个 cpp 文件中有以下代码:

class Base
{
  public:
    //constructor
    Base() = delete;
};

class Derived : public Base
{
  public:
    //copy constructor
    Derived( const Derived & other ){};
};

int main( int argc, char* argv[] )
{
  //empty
}
Run Code Online (Sandbox Code Playgroud)

但是编译cpp文件会报错

exp.cpp:在复制构造函数'Derived::Derived(const Derived&)'中:
exp.cpp:15:37: 错误:使用已删除的函数'Base::Base()'
Derived(const Derived & other){};

exp.cpp:7:5: 注意:这里声明
Base() = delete;
^~~~

我不明白为什么。当您为派生类定义复制构造函数时,基类默认构造函数如何发挥作用?

c++ constructor derived-class copy-constructor

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

存储后的 std::atomic 地址

我似乎无法在商店之后获得原子对象的地址。

例如

std::atomic<int> i;
std::atomic<int>* p = &++i; // doesn't work
auto* p = &++i; // doesn't work
// below works:
++i;
auto* p = &i;
Run Code Online (Sandbox Code Playgroud)

这里发生了什么,为什么?

澄清一下:我知道它返回一个 r 值。为什么它不返回原始对象,this?这是一个有目的的设计选择还是一个疏忽?

更具体地说,这个要求的幕后发生了什么?

c++ operator-overloading language-lawyer stdatomic c++17

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

拒绝 C 规则“条件表达式不产生左值”的动机是什么?

拒绝C规则的动机是什么a conditional expression does not yield an lvalue

换句话说:在 C 中,它是not yield an lvalue. 为什么在 C++ 中这种动机被拒绝(或重新考虑)?

c++ conditional-operator lvalue language-lawyer

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

(多字类型名称){表达式列表}合法吗?

考虑:

\n
(long long){1};\n
Run Code Online (Sandbox Code Playgroud)\n

It\xe2\x80\x99s 不是C 风格的转换表达式每个 [expr.cast]/1 的

\n
\n

表达式 (T) 强制转换表达式的结果为 T 类型。如果 T 是左值引用类型或对函数类型的右值引用,则结果是左值;如果 T 是对对象类型的右值引用,则结果是 xvalue;否则结果是纯右值。

\n
\n
\n

强制转换表达式:

\n
    \n
  • 一元表达式
  • \n
  • ( type-id ) 强制转换表达式
  • \n
\n
\n

{1}不应该是强制转换表达式

\n

它也不是每个 [expr.type.conv]/1 的函数式转换表达式:

\n
\n

简单类型说明符或类型名说明符后跟带括号的可选表达式列表或大括号初始化列表(初始化程序),在给定初始化程序的情况下构造指定类型的值。如果该类型是推导类类型的占位符,则它将替换为本子条款其余部分的类模板推导重载决策所选择的函数的返回类型。否则,如果类型包含占位符类型,则将其替换为由占位符类型推导 ([dcl.type.auto.deduct]) 确定的类型。

\n
\n
\n

简单类型说明符:

\n
    \n
  • 嵌套名称说明符 opt 类型名称
  • \n
  • 嵌套名称说明符模板简单模板 ID
  • \n
  • decl类型说明符
  • \n
  • 占位符类型说明符
  • \n
  • 嵌套名称说明符 opt 模板名称
  • \n
  • 字符
  • \n
  • char8_\xc2\xadt
  • \n
  • char16_\xc2\xadt
  • \n …

c++ grammar casting language-lawyer braced-init-list

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

为什么我不能重载operator =?

我想让以下代码工作:

Mylist lst;
vector<int> v = lst;
Run Code Online (Sandbox Code Playgroud)

所以我看到我需要将列表转换为矢量.我试过这段代码:

vector<int> operator=(vector<int> v, const List & l) {
    return v; // more profound stuff later :-)
}
Run Code Online (Sandbox Code Playgroud)

(把它放在课外).不幸的是Visual Studio抛出了我:"错误:'operator ='必须是成员函数".我不明白 - 我该怎么办?我不能把这个功能放在矢量类中......你可以帮帮我吗?谢谢!

c++ operator-overloading assignment-operator implicit-conversion operator-keyword

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

另一个"无效初始化类型的引用"错误

我的课堂上有这样的容器:

protected:
std::map<const AAA*, std::set<BBB*> > conn;
Run Code Online (Sandbox Code Playgroud)

以下两个getter函数都可以正常工作:

std::map<const AAA*, std::set<BBB*> > & getConnectors()       {return connectors;}
std::map<const AAA*, std::set<BBB*> >   getConnectors() const {return connectors;}
Run Code Online (Sandbox Code Playgroud)

但是&和const一起,Nope.Gives错误:

std::map<const AAA*, std::set<BBB*> > & getConnectors() const {return connectors;} //error
Run Code Online (Sandbox Code Playgroud)

错误是:

/home.../Multi.hpp:65:108: error: invalid initialization of reference of type ‘std::map<const AAA*, std::set<BBB*> >&’ from expression of type ‘const std::map<const AAA*, std::set<BBB*> >’
make[2]: *** [CMakeFiles/SimMobility.dir/main.cpp.o] Error 1
Run Code Online (Sandbox Code Playgroud)

为什么我得到这个,请问我怎么解决呢

谢谢

c++ const reference

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

C++中复制对象的动态绑定

我在虚函数中遇到问题:以下是一些代码示例:

class A
   {
      public : virtual  void print(void)
           {
              cout<< "A::print()"<<endl;
           }
    };
 class B : public A
    {
      public : virtual void print(void)
           {
               cout<<"B::print()"<<endl;
           }
    };
 class C : public A
    {
      public : void print(void)
            {
               cout<<"C::print()"<<endl;
            }
     };
  int main(void)
     {
         A a,*pa,*pb,*pc;
         B b;
         C c;
         pa=&a;
         pb=&b;
         pc=&c;

         pa->print();
         pb->print();
         pc->print();

         a=b;
         a.print();
         return 0;
       }
Run Code Online (Sandbox Code Playgroud)

结果:A :: print()B :: print()C :: print()A :: print()

我知道它是一个多态,并且知道有一个名为virtual-function-table的表,但我不知道它是如何实现的,并且

   a=b;
   a.print();
Run Code Online (Sandbox Code Playgroud)

结果是:A :: print()不是B :: print(),为什么它没有多态性.谢谢!

c++ virtual-functions dynamic-binding

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

为什么要调用基函数?

在以下代码中:

#include <iostream>
using namespace std;

class A {
    public:
    A() {
        cout << " A constructor \n";
        sum(2,4);
    }
    virtual int sum(int a, int b){
        cout << "Base sum \n";
        return a + b;
    }
};

class B : public A {
    public:
    B() : A() {
        cout << " B constructor \n";
    }

    int sum(int a, int b){
        cout << "Overloaded sum \n";
        return (a + b) * 10;
    }
};

int main(){
    A* a = …
Run Code Online (Sandbox Code Playgroud)

c++ constructor virtual-functions vtable

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

命名"左值"和"右值"背后的原因是什么?

在C/C++中命名"左值"和"右值"背后的原因是什么(我知道它们是如何运作的)?

c c++ terminology rvalue lvalue

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