小编Jon*_*ely的帖子

为什么C++语言设计者会不断重复使用关键字?

支持重新使用短关键字(并添加依赖于上下文的含义)而不仅仅是添加更多关键字的主要论点是什么?

是否只是想要避免破坏可能已经使用建议的新关键字的现有代码,还是有更深层次的原因?

C++ 11中新的"枚举类"让我想到了这一点,但这是一个通用的语言设计问题.

c++ language-design keyword c++11

64
推荐指数
4
解决办法
6276
查看次数

将空指针传递给placement new

默认的放置new运算符在18.6 [support.dynamic]1中声明,带有非抛出异常规范:

void* operator new (std::size_t size, void* ptr) noexcept;
Run Code Online (Sandbox Code Playgroud)

这个函数没有任何作用,除非return ptr;它是合理的noexcept,但是根据5.3.4 [expr.new]15这意味着编译器必须检查它在调用对象的构造函数之前不返回null:

-15-
[ 注意:除非使用非抛出异常规范(15.4)声明分配函数,否则它表示无法通过抛出std::bad_alloc异常来分配存储(第15,18.6.2.1节); 否则返回非空指针.如果使用非抛出异常规范声明分配函数,则返回null以指示无法分配存储,否则返回非空指针.-end note ]如果分配函数返回null,则不进行初始化,不应调用解除分配函数,并且new-expression的值应为null.

在我看来(特别是对于放置new,而不是一般)这个空检查是一个不幸的性能命中,尽管很小.

我一直在调试一些代码,其中new在一个性能敏感的代码路径中使用了放置,以改进编译器的代码生成,并在程序集中观察到null检查.通过提供new使用抛出异常规范声明的特定于类的放置重载(即使它不可能抛出),删除了条件分支,这也允许编译器为周围的内联函数生成更小的代码.说放置new函数的结果可能会抛出,即使它不能,也是可测量的更好的代码.

所以我一直想知道是否真的需要进行空检查new.它返回null的唯一方法是将它传递给null.尽管写下来是可能的,而且显然是合法的:

void* ptr = nullptr;
Obj* obj = new (ptr) Obj();
assert( obj == nullptr );
Run Code Online (Sandbox Code Playgroud)

我不明白为什么这将是有益的,我认为它会更好,如果程序员有明确使用放置前检查null new

Obj* obj = ptr ? new (ptr) Obj() : nullptr;
Run Code Online (Sandbox Code Playgroud)

有没有人需要放置new来正确处理空指针的情况?(即不添加作为ptr有效内存位置的显式检查.)

我想知道禁止将空指针传递给默认的放置 …

c++ placement-new micro-optimization noexcept

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

std :: scoped_allocator_adaptor的目的是什么?

在C++ 11标准中,我们std::scoped_allocator_adaptor在动态内存管理库中.这个班级最重要的用例是什么?

c++ containers memory-management allocator c++11

28
推荐指数
2
解决办法
2575
查看次数

Fast Delegate(等)背后的想法是否用于优化std :: function?

已经提出了C++"委托"的建议,其开销低于boost::function:

是否已将这些想法用于实施std::function,从而产生更好的性能boost::function?有谁比较过std::functionvs 的表现boost::function

我想知道这个特别适用于英特尔64位架构上的GCC编译器和libstdc ++,但欢迎其他编译器的信息(例如Clang).

c++ performance boost c++11 std-function

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

std :: function构造函数和nullptr

为什么以下代码打印"0"作为输出?

#include <functional>
#include <iostream>

int main()
{
    typedef void (*fp_t)();

    fp_t fp = nullptr;

    std::function<void()> f = fp;
    std::cout << (f == nullptr) << '\n';
}
Run Code Online (Sandbox Code Playgroud)

我用gcc 4.7.2和MSVC-11.0测试了它.

我认为它应该打印"1",因为标准的以下引用:

ISO/IEC 14882:2011

20.8.11.2.1 function construct/copy/destroy [func.wrap.func.con]

template<class F> function(F f);
template<class F, class A> function(allocator_arg_t, const A& a, F f);

...

8 后置条件: !*this如果满足以下任何条件: - fNULL 函数指针.- fNULL指向成员的指针.- F是函数类模板的实例,和!f

c++ c++11

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

如何避免错误:在抛出'std :: logic_error'的实例后调用terminate what():basic_string :: _ S_construct null无效

if(player!=NULL)
    player->shuffled();
Run Code Online (Sandbox Code Playgroud)

我这样做是为了避免将null引用传递给字符串构造函数,但是在编译时仍然会出错.

c++ libstdc++

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

为什么C++ 14中没有std :: allocate_unique函数?

为什么在shared_ptr没有allocate_unique的unique_ptr情况下有allocate_shared?
我想使用自己的分配器创建一个unique_ptr:我是否必须自己分配缓冲区然后将其分配给unique_ptr?
这似乎是一个明显的成语.

c++ std c++14

17
推荐指数
2
解决办法
3032
查看次数

通过同步延长线程的生命周期(C++ 11)

我有一个程序,其函数将指针作为arg和main.主要是创建n个线程,每个线程根据传递的内容在不同的内存区域运行arg.然后连接线程,主要在区域之间执行一些数据混合,并创建n个新线程,这些线程执行与旧线程相同的操作.

为了改进程序,我想保持线程活着,消除创建它们所需的长时间.线程应在主要工作时休眠,并在必须再次出现时通知.同样,主要应该在线程工作时等待,就像连接一样.

我无法最终实现这一点,总是陷入僵局.

简单的基线代码,任何有关如何修改它的提示将非常感激

#include <thread>
#include <climits>

...

void myfunc(void * p) {
  do_something(p);
}

int main(){
  void * myp[n_threads] {a_location, another_location,...};
  std::thread mythread[n_threads];
  for (unsigned long int j=0; j < ULONG_MAX; j++) {
    for (unsigned int i=0; i < n_threads; i++) {
      mythread[i] = std::thread(myfunc, myp[i]);
    }
    for (unsigned int i=0; i < n_threads; i++) {
      mythread[i].join();
    }
    mix_data(myp); 
  }
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

c++ multithreading thread-safety c++11

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

c#setter中的堆栈溢出异常

这很容易解释:这很有效

using System;
using ConstraintSet = System.Collections.Generic.Dictionary<System.String, double>;

namespace ConsoleApplication2
{
    class test
    {
        public ConstraintSet a { get; set; }
        public test()
        {
            a = new ConstraintSet();
        }
        static void Main(string[] args)
        {
            test abc = new test();
            Console.WriteLine("done");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这不

using System;
using ConstraintSet = System.Collections.Generic.Dictionary<System.String, double>;

namespace ConsoleApplication2
{
    class test
    {
        public ConstraintSet a { get { return a; } set { a = value; } }
        public test()
        {
            a = new ConstraintSet(); …
Run Code Online (Sandbox Code Playgroud)

c# stack-overflow setter callstack

14
推荐指数
3
解决办法
8133
查看次数

为什么排除的文件会在我的git稀疏结帐中重新出现?

我使用GCC git镜像,因为我只使用C和C++前端,我使用git的稀疏checkout功能来排除我不需要的数百个文件:

$ git config core.sparseCheckout
true
$ cat .git/info/sparse-checkout 
/*
!gnattools/
!libada/
!libgfortran/
!libgo/
!libjava/
!libobjc/
!libquadmath/
!gcc/ada/
!gcc/fortran/
!gcc/go/
!gcc/java/
!gcc/objc/
!gcc/objcp/
!gcc/testsuite/ada/
!gcc/testsuite/gfortran.dg/
!gcc/testsuite/gfortran.fortran-torture/
!gcc/testsuite/gnat.dg/
!gcc/testsuite/go.dg/
!gcc/testsuite/go.go-torture/
!gcc/testsuite/go.test/
!gcc/testsuite/objc/
!gcc/testsuite/objc.dg/
!gcc/testsuite/obj-c++.dg/
!gcc/testsuite/objc-obj-c++-shared/
Run Code Online (Sandbox Code Playgroud)

这工作了一段时间,但后来我发现其中一些被排除的文件已经返回,有时很多:

$ ls gnattools/
ChangeLog  configure  configure.ac  Makefile.in
$ ls  gcc/fortran/ | wc -l 
86
Run Code Online (Sandbox Code Playgroud)

我不确定文件何时重新出现,我做了很多切换到不同的分支(远程跟踪和本地),这是一个非常繁忙的回购,所以有新的变化经常拉.

作为git的相对新手,我不知道如何"重置"我的工作树以再次摆脱这些文件.

作为一个实验,我尝试禁用稀疏检出和拉动,认为我可以再次启用sparseCheckout以某种方式更新树,但这不能很好地工作:

$ git config core.sparseCheckout false
$ git config core.sparseCheckout 
false
$ git pull
remote: Counting objects: 276, done.
remote: Compressing objects: 100% (115/115), …
Run Code Online (Sandbox Code Playgroud)

git sparse-checkout

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