小编gal*_*tte的帖子

现代C++编译器是否能够在某些条件下避免两次调用const函数?

例如,如果我有这个代码:

class SomeDataProcessor
{
public:
    bool calc(const SomeData & d1, const SomeData & d2) const;
private:
    //Some non-mutable, non-static member variables
}

SomeDataProcessor sdp;
SomeData data1;
SomeData data2;

someObscureFunction(sdp.calc(data1, data2),
                    sdp.calc(data1, data2));
Run Code Online (Sandbox Code Playgroud)

让我们考虑可能等效的代码:

bool b = sdp.calc(data1, data2);
someObscureFunction(b,b);
Run Code Online (Sandbox Code Playgroud)

为了使其有效,该calc()函数应满足一些要求,对于该示例,我调用该属性_pure_const_formula_

A _pure_const_formula_会:

  • 不更改任何成员,静态或全局变量状态
  • 仅限通话_pure_const_formula_功能
  • 也许其他一些我没有想到的条件

例如,调用随机数生成器不符合这些要求.

是否允许编译器用第二个代码替换第一个代码,即使它需要递归地挖掘到被调用的函数中?现代编译器能够做到这一点吗?

c++ compiler-construction optimization call

37
推荐指数
3
解决办法
5061
查看次数

将字符串移出std :: ostringstream

如果我构造一个由空格分隔的浮点值列表组成的字符串,使用std::ostringstream:

std::ostringstream ss;
unsigned int s = floatData.size();
for(unsigned int i=0;i<s;i++)
{
    ss << floatData[i] << " ";
}
Run Code Online (Sandbox Code Playgroud)

然后我得到一个结果std::string:

std::string textValues(ss.str());
Run Code Online (Sandbox Code Playgroud)

但是,这将导致不必要的字符串内容的深层副本,因为ss将不再使用.

有没有办法在不复制整个内容的情况下构造字符串?

c++ ostringstream move-semantics c++11

27
推荐指数
3
解决办法
3628
查看次数

成员函数上的Const引用限定符

我在anwser中看到过: 通过右值引用返回更有效率吗?

成员函数定义:

Beta_ab const& getAB() const& { return ab; }
Run Code Online (Sandbox Code Playgroud)

我熟悉成员函数的cv-qualifier(const),但不熟悉const&.

最后的const&意思是什么?

c++ reference member-functions const-reference

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

c ++ libstd同时计算sin和cos

在C库中math.h,有一个sincos非常有效的函数,因为它在更接近单个调用sin()或者cos()调用两者的总时间的时间内计算正弦和余弦.

C++标准库中有这样的功能吗?

c++ math trigonometry libstdc++

12
推荐指数
3
解决办法
6530
查看次数

实现类似于Qt的高性能互斥锁

我有一个多线程科学应用程序,其中几个计算线程(每个核心一个)必须将其结果存储在公共缓冲区中.这需要互斥机制.

工作线程只花费一小部分时间写入缓冲区,因此互斥锁在大多数时间都处于解锁状态,并且锁定很有可能立即成功而无需等待另一个线程解锁.

目前,我已经使用Qt的QMutex执行任务,并且运行良好:互斥锁的开销可以忽略不计.

但是,我必须将它移植到c ++ 11/STL.使用std :: mutex时,性能下降了66%,并且线程花费大部分时间来锁定互斥锁.

在另一个问题之后,我认为Qt使用基于简单原子标志的快速锁定机制,针对互斥锁尚未锁定的情况进行了优化.并发锁定发生时会回退到系统互斥锁.

我想在STL中实现这一点.是否有一种基于std :: atomic和std :: mutex的简单方法?我已经深入研究了Qt的代码,但对于我的使用似乎过于复杂(我不需要锁定超时,pimpl,小占用空间等......).

编辑:我试过一个螺旋锁,但这不能很好地工作,因为:

定期(每隔几秒),另一个线程锁定互斥锁并刷新缓冲区.这需要一些时间,因此此时所有工作线程都会被阻止.自旋锁使调度繁忙,导致刷新比使用适当的互斥锁慢10-100倍.这是不可接受的

编辑:我试过这个,但它不起作用(锁定所有线程)

class Mutex
{
public:
    Mutex() : lockCounter(0) { }

    void lock()
    {
        if(lockCounter.fetch_add(1, std::memory_order_acquire)>0)
        {
            std::unique_lock<std::mutex> lock(internalMutex);
            cv.wait(lock);
        }
    }

    void unlock();
    {
        if(lockCounter.fetch_sub(1, std::memory_order_release)>1)
        {
            cv.notify_one();
        }
    }


private:
    std::atomic<int> lockCounter;
    std::mutex internalMutex;
    std::condition_variable cv;
};
Run Code Online (Sandbox Code Playgroud)

谢谢!

编辑:最终解决方案

MikeMB的快速互斥体工作得非常好.

作为最终的解决方案,我做了:

  • 使用带有try_lock的简单螺旋锁
  • 当一个线程无法try_lock而不是等待时,它们会填充一个队列(不与其他线程共享)并继续
  • 当线程获得锁定时,它会使用当前结果更新缓冲区,但也会将结果存储在队列中(它会处理其队列)
  • 缓冲区刷新效率更高:阻塞部分只交换两个指针.

c++ qt mutex stl c++11

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

c ++中的复杂dynamic_cast

我在C++中有以下情况:

  • 抽象基类Abstract1Abstract2.他们是无关的.
  • 一类Foo来自推导Abstract1Abstract2

我在一个编译单元,我没有关于类的信息Foo(没有声明,没有定义).只有Abstract1而且Abstract2众所周知.(实际上,Foo甚至在DLL中定义)

将dynamic_cast的允许从铸造Abstract1*Abstract2*?这是标准吗?

c++ polymorphism dynamic-cast language-lawyer cross-cast

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

Can a virtual function be a candidate to RVO (return value optimization)?

Are C++ compilers able to apply RVO for virtual functions?

In this case:

class AbstractReader
{
//...
public:
    virtual std::vector<float> getFloatVector() = 0;
//...
}

class XmlReader : public AbstractReader
{
//...
public:
    virtual std::vector<float> getFloatVector()
    {
        std::vector<float> result;

        //Do some parsing here...

        return result;
    }
//...
}



class BinaryReader : public AbstractReader
{
//...
public:
    virtual std::vector<float> getFloatVector()
    {
        std::vector<float> result;

        //Do some decoding here...

        return result;
    }
//...
}
Run Code Online (Sandbox Code Playgroud)

Can RVO apply to return result; lines? I would …

c++ virtual move rvo

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

在"char类型"模板化类中使用字符串litterals

我在C模板类++这需要作为char_type模板参数中的字符类型,如char,wchar_t,char32_t等...的类,然后使用std::basic_string<char_type>在代码中.

然后在课堂的某个地方填写一个表格,例如"&amp;".这并不是因为根据模板字符类型的工作,我们需要使用"&amp;",L"&amp;",U"&amp;"...

有没有办法避免专门用于初始化表的模板函数,例如使用一些标准函数来转换字符串litterals?

由于这些是转义序列,因此它们不包含除ASCII字符之外的任何内容.

c++ templates widechar

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

不同的toctree标题和文档标题,仅在文档源中指定

在toctree中插入文档时,显示的链接是文档的主标题.所以当我这样做时:

.. toctree::
   materials/diffuse
   materials/glossy
   materials/specular
Run Code Online (Sandbox Code Playgroud)

我明白了:

物料

  • 漫射材料
  • 有光泽的材料
  • 镜面材料

"材料"这个词在toctree中显然是多余的,但在文档标题中很重要,以便更好地理解.

RST允许我写这个:

.. toctree::
   Diffuse<materials/diffuse>
   Glossy<materials/glossy>
   Specular<materials/specular>
Run Code Online (Sandbox Code Playgroud)

但我不喜欢这样,因为重命名文档需要更新索引toctree,链接更新是我从MediaWiki转到Sphinx的原因.此外,这会禁用在toctree中使用:glob:和wildcards

问题:有没有办法在叶子文档本身中指定一个toctree标题,例如在"diffuse.rst"中作为元属性?

谢谢!

restructuredtext python-sphinx

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

std :: condition_variable :: with谓词等待

在std :: condition_variable的文档中,使用谓词函数作为参数的wait()重载。该函数将一直等到谓词函数为true的第一次wake_up。

文档中

据说这相当于:

while (!pred()) {
    wait(lock);
}
Run Code Online (Sandbox Code Playgroud)

但是也:

在等待特定条件变为真时,可以使用此重载来忽略虚假唤醒。请注意,在进入此方法之前,必须先获取锁,在wait(lock)退出后也必须重新获取它,即锁可以用作pred()访问的保护。

我不确定这些是严格等同的(在这种情况下,我更喜欢普通的while循环,而在我的情况下,这种循环比带有lambda的重载更易于阅读),或者重载(可能取决于实现)更有效?

为了避免测试条件为假时唤醒,实现是否可以在唤醒等待线程之前评估通知线程中的谓词?这里需要c ++线程大师...

谢谢

c++ multithreading std condition-variable c++11

6
推荐指数
2
解决办法
5277
查看次数