小编Arv*_*vid的帖子

内存映射文件和指向易失性对象的指针

我对volatileC和C++ 语义的理解是它将内存访问转化为(可观察的)副作用.每当读取或写入内存映射文件(或共享内存)时,我都希望指针是volatile限定的,以表明这实际上是I/O. (John Regehr写了一篇关于语义的非常好的文章volatile).

此外,我希望使用像memcpy()访问共享内存的函数是不正确的,因为签名表明挥发性资格被丢弃,并且内存访问不被视为I/O.

在我看来,这是一个赞成的论据std::copy(),其中volatile限定符不会被丢弃,并且内存访问被正确地视为I/O.

但是,我使用指向易失性对象的指针和std::copy()访问内存映射文件的经验是,它比仅使用它要慢几个数量级memcpy().我很想得出结论,或许clang和GCC在对待他们时过于保守volatile.是这样的吗?

对于访问共享内存有什么指导volatile,如果我想遵循标准的字母并将它归还给我依赖的语义?


标准[intro.execution]§14的相关引用:

读取由volatile glvalue指定的对象,修改对象,调用库I/O函数或调用执行任何这些操作的函数都是副作用,这些都是执行环境状态的变化.表达式(或子表达式)的评估通常包括值计算(包括确定用于glvalue评估的对象的身份以及获取先前分配给用于prvalue评估的对象的值)和启动副作用.当对库I/O函数的调用返回或通过volatile glvalue进行访问时,即使调用所隐含的某些外部操作(例如I/O本身)或易失性访问,也会认为副作用已完成可能尚未完成.

c c++ mmap volatile language-lawyer

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

是shared_ptr的raw-pointer构造函数是一个错误?

事后看来,给定的是make_shared,如果shared_ptr用C++ 11引入它,会有一个带有原始指针的构造函数吗?

有没有强大的论据或用例支持这个构造函数?

这本来是可以避免的有据可查的陷阱异常安全内存分配/性能优势利用make_shared.

我认为需要shared_ptr构建的另一个优点make_shared是它可能是引擎盖下的单个指针,降低了它的内存使用并使atomic_compare_exchange之类的东西变得更简单(并且可能更高效).(请参阅C++中的演示文稿)

编辑

我知道一个shared_ptr基本上是一个intrusive_ptr(对象和控制块合并)会缺少当前std :: shared_ptr所具有的功能.喜欢:

  1. 将对象与控制块分开释放的能力(如果你长期生活在weak_ptrs中,这很好)

  2. 与提供原始指针的库的兼容性以及释放它们的责任

  3. 使用自定义删除程序保留任意资源的能力(或者对于非拥有指针没有删除程序)

  4. 能够在保持父对象存活的同时指向子对象(例如成员).

我建议的是,这些功能可能不常用(或者在使用它作为raii-wrapper的情况下)可能不是最合适的,以保证额外的费用:

  1. 一个指向控制块的单独指针
  2. (可能)更复杂的atomic_compare_exchange逻辑,可能不值得.

在C++ 98世界中(引入了shared_ptr),make_shared不太实用且用户友好性较差(缺乏完美的转发需要参考包装器和缺少可变参数模板使得实现笨重).

c++ shared-ptr make-shared c++11

8
推荐指数
3
解决办法
1788
查看次数

在try-catch块之外访问变量

我有以下代码:

class ClassA
{
public:
    ClassA(std::string str);
    std::string GetSomething();
};

int main()
{
    std::string s = "";
    try
    {
        ClassA a = ClassA(s);
    }
    catch(...)
    {
        //Do something
        exit(1);
    }

    std::string result = a.GetSomething();

    //Some large amount of code using 'a' out there.
}
Run Code Online (Sandbox Code Playgroud)

我想最后一行可以访问a变量.我怎么能实现这一点,因为ClassA没有默认构造函数ClassA(),我不想使用指针?是添加默认构造函数的唯一方法ClassA吗?

c++ c++11

7
推荐指数
2
解决办法
1871
查看次数

为什么Kademlia如何构建其路由表呢?

据我所知,Kademlia路由表由160个桶组成.

根据节点的前缀长度(本地节点密钥和节点的XOR中的前导未设置位数),将节点放入0-159个桶中.

为什么会这样,是否有任何性能优势(除了通过迭代160*20节点找到最接近的是不可行的事实)?

routing p2p dht kademlia

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

修改std :: vector函数(继承?)

我正在将一些Fortran90代码移植到C++中(因为我很愚蠢,为了保存"为什么?!").

Fortran允许在数组上指定范围,特别是从负值开始,例如

double precision :: NameOfArray(FirstSize, -3:3)
Run Code Online (Sandbox Code Playgroud)

我可以用C++编写这样的东西

std::array<std::array<double, 7>, FirstSize> NameOfArray;
Run Code Online (Sandbox Code Playgroud)

但现在我必须像索引一样NameOfArray[0:FirstSize-1][0:6].如果我想使用Fortran样式索引进行索引,我可以写一下

template <typename T, size_t N, int start>
class customArray
{
public:
    T& operator[](const int idx) { return data_[idx+start]; }
private:
    std::array<T,N> data_;
}
Run Code Online (Sandbox Code Playgroud)

然后

customArray<double, 7, -3> NameOfArray;
NameOfArray[-3] = 5.2;
NameOfArray[3] = 2.5;
NameOfArray[4] = 3.14; // This is out of bounds, 
                       // despite being a std::array of 7 elements
Run Code Online (Sandbox Code Playgroud)

所以 - 一般的想法是"不要在这里继承std ::'容器类'".我的理解是,这是因为,例如,std :: vector没有虚拟析构函数,因此不应该(不能?)以多态方式使用.

是否有一些其他的方式,我可以使用std::array,std::vector等等,并得到他们的职能"免费",同时覆盖特定的功能?

template<typename T, size_t …
Run Code Online (Sandbox Code Playgroud)

c++ inheritance overloading operator-overloading c++11

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