标签: c++

std :: vector中的自定义分配器

是否可以使用自定义分配器进行std::vector内部分配?如果有,怎么样?

c++ stl allocator c++11

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

使用Qt自然地对文件名进行排序

我正在阅读目录内容使用QDir::entryList().其中的文件名结构如下:

index_randomNumber.png
Run Code Online (Sandbox Code Playgroud)

我需要按照indexWindows资源管理器对文件进行排序的方式排序,以便我得到

0_0815.png
1_4711.png
2_2063.png
...
Run Code Online (Sandbox Code Playgroud)

而不是排序通过QDir::Name给我:

0_0815.png
10000_6661.png
10001_7401.png
...
Run Code Online (Sandbox Code Playgroud)

在Qt中是否有内置的方法来实现这一点,如果没有,那么实现它的正确位置是什么?

c++ qt natural-sort

24
推荐指数
2
解决办法
1万
查看次数

最快的内联装配螺旋锁

我正在用c ++编写多线程应用程序,其中性能至关重要.我需要在线程之间复制小结构时使用大量锁定,为此我选择使用自旋锁.

我已经做了一些研究和速度测试,我发现大多数实现大致同样快:

  • MicroFts CRITICAL_SECTION,SpinCount设置为1000,得分约140个单位
  • 使用Microsofts 实现此算法 InterlockedCompareExchange得分约95个时间单位
  • 我也尝试使用一些内联汇编,__asm {}使用类似这样的代码,它得分约70个时间单位,但我不确定是否已创建适当的内存屏障.

编辑:这里给出的时间是2个线程锁定和解锁螺旋锁1,000,000次所需的时间.

我知道这并没有太大的区别,但是由于自旋锁是一个使用频繁的对象,人们会认为程序员会同意以最快的方式制作自旋锁.谷歌搜索导致许多不同的方法.我认为如果使用内联汇编并使用指令而不是比较32位寄存器来实现上述方法将是最快的CMPXCHG8B.此外,必须考虑内存障碍,这可以通过LOCK CMPXHG8B(我认为?)来完成,这保证了内核之间共享内存的"专有权".最后[有人建议]对于繁忙的等待应该伴随NOP:REP,这将使超线程处理器切换到另一个线程,但我不确定这是否是真的?

根据我对不同螺旋锁的性能测试,可以看出没有太大区别,但出于纯粹的学术目的,我想知道哪一个是最快的.但是由于我在汇编语言和内存障碍方面的经验非常有限,如果有人可以为我在LOCK CMPXCHG8B中提供的最后一个示例编写汇编代码并在以下模板中使用适当的内存屏障,我会很高兴:

__asm
{
     spin_lock:
         ;locking code.
     spin_unlock:
         ;unlocking code.
}
Run Code Online (Sandbox Code Playgroud)

c++ x86 assembly spinlock memory-barriers

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

何时使用`static_assert`而不是SFINAE?

我一直在使用(并且看到用过)static_assert来标记模板参数值的不需要的值.然而,对于我遇到的所有情况,通过SFINAE禁用那些不需要的值似乎更好,更优雅.例如

template<typename T,
         class = std::enable_if<std::is_floating_point<T>::value>::type>
struct Foo { ... };
Run Code Online (Sandbox Code Playgroud)

代替

template<typename T>
struct Foo {
  static_assert(std::is_floating_point<T>::value,
                "Foo<T>: T must be floating point :-(");
  ...
};
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:何时使用static_assert而不是SFINAE?为什么?

编辑

我认为到目前为止我所学到的是以下内容

1 SFINAE是一个多功能且功能强大但可能非常复杂的工具,可用于许多任务,包括功能过载解决(有些人认为这是其唯一目的).

2 SFINAE可以以一种相对简单的方式使用static_assert,除非它出现在(类或函数的)声明中而不是它的定义(或者是否可以插入static_assert一个类,例如,类前向声明​​?) .这使得更加逐字,更清晰的代码.然而,因为SFINAE很复杂,所以它往往比简单的更难static_assert.

3另一方面,static_assert有一个更清晰的编译器错误消息的好处,有些人似乎认为这两者的主要目的.

c++ templates static-assert sfinae c++11

24
推荐指数
4
解决办法
3761
查看次数

为什么移动包含std :: stringstream的类的语义会导致编译器错误?

如何让这个简单的类移动?我认为是正确的只会产生一堵错误之墙......

#include <iostream>
#include <sstream>
#include <utility>

class message
{
    public:
        message() = default;

        // Move constructor
        message( message &&other ) :
            stream_( std::move( other.stream_ ) ) // Nope
        {}

        // Move assignment
        message &operator=( message &&other )
        {
            if ( this != &other )
            {
                stream_ = std::move( other.stream_ ); // Nope #2
            }
            return *this;
        }

    private:
        message( const message & ) = delete;
        message &operator=( const message & ) = delete;

        std::stringstream stream_;
        // Other member variables …
Run Code Online (Sandbox Code Playgroud)

c++ g++ stringstream move-semantics c++11

24
推荐指数
2
解决办法
7188
查看次数

什么构成C++ 11中"移动"对象的有效状态?

我一直在试图解决C++ 11中的移动语义应该如何工作,而且我很难理解移动对象需要满足的条件.看看这里答案并没有真正解决我的问题,因为无法看到如何以合理的方式将它应用于pimpl对象,尽管移动语义的参数非常适合pimpls.

我的问题最简单的说明涉及pimpl习语,如下所示:

class Foo {
    std::unique_ptr<FooImpl> impl_;
public:
    // Inlining FooImpl's constructors for brevity's sake; otherwise it 
    // defeats the point.
    Foo() : impl_(new FooImpl()) {}

    Foo(const Foo & rhs) : impl_(new FooImpl(*rhs.impl_)) {}

    Foo(Foo && rhs) : impl_(std::move(rhs.impl_)) {}

    Foo & operator=(Foo rhs) 
    {
        std::swap(impl_, rhs.impl_);

        return *this;
    }

    void do_stuff () 
    {
        impl_->do_stuff;
    }
};
Run Code Online (Sandbox Code Playgroud)

现在,一旦我离开了,我该怎么办Foo?我可以安全地销毁移动的物体,我可以分配给它,这两者都绝对是至关重要的.但是,如果我尝试do_stuff使用我的Foo,它会爆炸.在我为我的定义添加移动语义之前Foo,每个人都Foo满足了它的不变性do_stuff,而现在已不再是这样了.目前似乎并没有被大量的替代品,或者说,因为(例如)将被移至距离Foo …

c++ pimpl-idiom invariants move-semantics c++11

24
推荐指数
2
解决办法
4365
查看次数

如何处理或避免C++中的堆栈溢出

在C++中,堆栈溢出通常会导致程序无法恢复的崩溃.对于需要非常强大的程序,这是一种不可接受的行为,特别是因为堆栈大小有限.关于如何处理问题的一些问题.

  1. 有没有办法通过一般技术来防止堆栈溢出.(一种可扩展,强大的解决方案,包括处理大量堆栈的外部库等)

  2. 有没有办法处理堆栈溢出,以防它们发生?优选地,堆栈被解开,直到有处理器来处理该类问题.

  3. 有些语言,有可扩展堆栈的线程.这样的东西在C++中是可能的吗?

关于C++行为解决方案的任何其他有用的评论将不胜感激.

c++ stack-overflow crash error-handling

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

关于C++中的局部和全局静态变量

C++ Primer说

在第一次执行通过对象的定义之前,初始化每个本地静态变量.当函数结束时,不会破坏局部静态; 程序终止时它们会被销毁.

局部静态变量与全局静态变量有什么不同?除了声明它们的位置之外,还有什么不同?

void foo () {   
    static int x = 0;
    ++x;

    cout << x << endl;
}

int main (int argc, char const *argv[]) {
    foo();  // 1
    foo();  // 2
    foo();  // 3
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

与之比较

static int x = 0;

void foo () {   
    ++x;

    cout << x << endl;
}

int main (int argc, char const *argv[]) {
    foo();  // 1
    foo();  // 2
    foo();  // 3
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c++ static

24
推荐指数
4
解决办法
3万
查看次数

装饰设计模式与继承?

我已经阅读了维基百科的装饰设计模式,以及该网站的代码示例.

我认为传统继承遵循'is-a'模式,而decorator遵循'has-a'模式.装饰者的调用约定看起来像'皮肤'上的'皮肤'......超过'核心'.例如

I* anXYZ = new Z( new Y( new X( new A ) ) );
Run Code Online (Sandbox Code Playgroud)

如上面的代码示例链接所示.

但是仍然有一些我不明白的问题:

  1. wiki是什么意思'装饰模式可以用来在运行时扩展(装饰)某个对象的功能'?'new ...(new ...(new ...))'是一个运行时调用,但很好但是'AwithXYZ anXYZ;' 是编译时的继承而且不好?

  2. 从代码示例链接中我可以看到,两个实现中类定义数量几乎相同.我记得在其他一些设计模式书中,比如"Head first design patterns".他们使用starbuzz咖啡作为例子,并说传统的继承将导致"阶级爆炸",因为对于每种咖啡组合,你会想出一个类.

    但在这种情况下装饰者是不是一样的?如果一个装饰器类可以接受任何抽象类并进行装饰,那么我猜它确实可以防止爆炸,但是从代码示例中,你可以得到确切的类定义,不能少......

有人会解释吗?

c++ design-patterns

24
推荐指数
2
解决办法
7430
查看次数

在range-for循环中访问索引

我有一个对象向量,并使用range-for循环迭代它.我用它来打印对象的函数,如下所示:

vector<thisObject> storedValues;
//put stuff in storedValues
for(auto i:storedValues)
{
   cout<<i.function();
}
Run Code Online (Sandbox Code Playgroud)

但我也想打印索引.我想要的输出是:

1: value
2: value
//etc
Run Code Online (Sandbox Code Playgroud)

我打算只使用我每次增加的计数器,但这看起来非常低效.有没有更好的办法?

c++ c++11

24
推荐指数
5
解决办法
1万
查看次数