小编Jer*_*ner的帖子

为什么允许在Visual Studio 2013下编译此代码?

这是一个非常简单的C++ 11程序,它测试了final关键字的使用,以防止类被子类化:

template<class T> class Base final
{
public:
   Base() {}

private:
   T t;
};

class Derived : public Base<int> {};

int main(int, char **)
{
   Derived d;
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果我尝试在Mac OS X(Clang)下编译上述程序,我会收到预期的错误消息:

jeremy-friesners-mac-pro-3:~ jaf$ g++ -std=c++11 ./temp.cpp
./temp.cpp:10:28: error: base 'Base' is marked 'final'
   class Derived : public Base<int> {};
                       ^
./temp.cpp:1:29: note: 'Base' declared here
   template<class T> class Base final
Run Code Online (Sandbox Code Playgroud)

但是,如果我使用Visual Studio 2013在Windows下编译相同的代码,它将编译没有错误.Base但是,如果我使该类非模板化,Visual Studio会识别该final关键字并发出错误.

这是Visual Studio 2013中的错误,还是我错过了关于如何final允许/期望关键字与模板化类一起操作的一些细微差别?

c++ templates final visual-studio-2013

18
推荐指数
2
解决办法
776
查看次数

在这个用例中,TCP_CORK和TCP_NODELAY之间是否有任何显着差异?

在写了关于TCP_NODELAY和TCP_CORK 的答案之后,我意识到我对TCP_CORK的细节点的了解一定是缺乏的,因为我不清楚为什么Linux开发人员认为有必要引入新的TCP_CORK标志,而不仅仅是依赖于应用程序在适当的时间设置或清除现有的TCP_NODELAY标志.

特别是,如果我有一个Linux应用程序想要通过TCP流发送()一些小的/非连续的数据片段而不支付200mS Nagle延迟税,同时最小化发送所需的数据包数量它,我可以这两种方式中的任何一种:

使用TCP_CORK(伪代码):

int optval = 1;
setsockopt(sk, SOL_TCP, TCP_CORK, &optval, sizeof(int));   // put a cork in it
send(sk, ..);
send(sk, ..);
send(sk, ..);
optval = 0;
setsockopt(sk, SOL_TCP, TCP_CORK, &optval, sizeof(int));   // release the cork
Run Code Online (Sandbox Code Playgroud)

或者使用TCP_NODELAY(伪代码):

int optval = 0;
setsockopt(sk, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(int));   // turn on Nagle's
send(sk, ..);
send(sk, ..);
send(sk, ..);
optval = 1;
setsockopt(sk, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(int));   // turn Nagle's back off
Run Code Online (Sandbox Code Playgroud)

多年来我一直在使用后一种技术并取得了良好的效果,并且它具有可移植到非Linux操作系统的优点(尽管在Linux之后你必须在关闭Nagle之后再次调用send(),以便确保数据包立即发送并避免Nagle-delay - send()'零字节就足够了).

现在Linux开发人员都很聪明,所以我怀疑上面的TCP_NODELAY用法从未发生过.必须有一些理由让他们认为这是不够的,这导致他们引入了一个新的/专有的TCP_CORK标志.任何人都能解释一下这个原因是什么吗?

linux tcp nagle

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

有没有办法禁止我的班级继承?

假设我有一个名为"Base"的类,以及一个名为"Derived"的类,它是Base的子类,并访问受保护的方法和Base的成员.

我现在想要做的就是让它没有其他类可以继承Derived.在Java中,我可以通过声明Derived类"final"来实现这一点.是否有一些C++技巧可以给我同样的效果?

(理想情况下,我希望除了Derived之外没有其他类可以将Base子类化.我不能只将所有代码放入同一个类或使用friend关键字,因为Base和Derived都是模板化的,模板参数比Derived少的基础....)

c++ final protected keyword subclassing

16
推荐指数
3
解决办法
4036
查看次数

编译时数据结构的数量结构?

在C++中,您可以这样做:

static const char * [4] = {
   "One fish",
   "Two fish",
   "Red fish",
   "Blue fish"
};
Run Code Online (Sandbox Code Playgroud)

...这为您提供了一个很好的只读数组数据结构,它不需要在运行时初始化任何CPU周期,因为所有数据都已经为您(在可执行文件的只读存储器页面中)布局了编译器.

但是如果我宁愿使用不同的数据结构而不是数组呢?例如,如果我希望我的数据结构通过密钥快速查找,我必须做这样的事情:

static std::map<int, const char *> map;

int main(int, char **)
{
   map.insert(555, "One fish");
   map.insert(666, "Two fish");
   map.insert(451, "Red fish");
   map.insert(626, "Blue fish");

   [... rest of program here...]
}
Run Code Online (Sandbox Code Playgroud)

...当地图数据结构在运行时被填充时,它不那么优雅且效率较低,即使在编译时已知所有必要的数据,因此该工作可以(理论上)完成.

我的问题是,在C++(或C++ 11)中是否有任何方法可以创建一个只读数据结构(如地图),其数据完全在编译时设置,因此预先填充并准备好在运行时,数组的方式是什么?

c++ compile-time c++11

16
推荐指数
2
解决办法
2214
查看次数

有没有办法检测远程对等体已关闭TCP套接字,而不读取它?

首先,一些背景来解释动机:我正在研究一个非常简单的基于select()的TCP"镜像代理",它允许两个防火墙的客户端间接地相互通信.两个客户端都连接到此服务器,并且只要两个客户端都连接,客户端A发送到服务器的任何TCP字节都将转发到客户端B,反之亦然.

这或多或少都有效,只有一个小问题:如果客户端A连接到服务器并在客户端B连接之前开始发送数据,则服务器没有任何地方可以放置数据.我不想在RAM中缓冲它,因为这可能最终使用大量的RAM; 我也不想丢弃数据,因为客户端B可能需要它.所以我选择了第三个选项,即在客户端B连接之前,不要在客户端A的套接字上选择() - for-read-ready.这样客户端A就会阻塞,直到一切准备就绪.

这或多或少也有效,但是在客户端A的套接字上没有选择准备就绪的副作用是,如果客户端A决定关闭他与服务器的TCP连接,则服务器不会收到有关该事实的通知 - - 至少,直到客户端B出现并且服务器最终在客户端A的套接字上选择for-ready-ready,读取任何未决数据,然后获得套接字关闭通知(即recv()返回0).

如果服务器有某种方式知道(及时)客户端A关闭他的TCP连接,我更喜欢它.有没有办法知道这个?在这种情况下轮询是可以接受的(例如,我可以让select()每分钟唤醒一次并在所有套接字上调用IsSocketStillConnected(sock),如果存在这样的函数).

c select tcp

16
推荐指数
2
解决办法
4万
查看次数

是按位还是保证评估排序?

说我有这个代码:

unsigned int func1();
unsigned int func2();
unsigned int func3();

unsigned int x = func1() | func2() | func3();
Run Code Online (Sandbox Code Playgroud)

C++是否保证首先调用func1(),然后调用func2(),然后调用func3()?

或者是否允许编译器以任何顺序调用函数?

此外,编译器是否允许在此处实现短路优化?(例如,如果func1()返回〜0,编译器是否可以决定不打扰调用func2()或func3(),因为它知道它们的返回值不可能影响分配给x的值?)

c++ operator-precedence short-circuiting bitwise-or

15
推荐指数
2
解决办法
722
查看次数

假设WAV或AIFF文件中的浮点样本将被标准化是否正确?

假设我有一个读取.WAV或.AIFF文件的程序,文件的音频被编码为浮点样本值.我的程序假设任何格式良好(基于浮点的).WAV或.AIFF文件只包含[-1.0f,+ 1.0f]范围内的样本值是否正确?我找不到解决这一点的WAV或AIFF规范中的任何内容.

如果这不是一个有效的假设,那么如何才能知道文件中音频的完整动态范围是什么?(我可以读取整个文件并找出文件的实际最小和最大样本值是什么,但是有两个问题:(1)如果文件非常大,那将是一个缓慢/昂贵的操作,(2) )它会丢失信息,因为如果文件的创建者打算让文件有一些"余量",以免在dbFS最大点播放,我的程序将无法检测到这一点)

floating-point normalization wav aiff

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

如何在不冒 OOM 杀手的风险的情况下 mmap() 大文件?

我有一个嵌入式 ARM Linux 机器,其 RAM 量有限(512MB)且没有交换空间,我需要在其上创建然后操作一个相当大的文件(~200MB)。将整个文件加载到 RAM 中,修改 RAM 中的内容,然后再次将其写回,有时会调用 OOM-killer,我想避免这种情况。

我解决这个问题的想法是使用mmap()这个文件映射到我的进程的虚拟地址空间;这样,对映射内存区域的读取和写入将转到本地闪存文件系统,并且可以避免 OOM 杀手,因为如果内存不足,Linux 可以只刷新一些 mmap() 的内存页回到磁盘以释放一些 RAM。(这可能会使我的程序变慢,但对于这个用例来说慢是可以的)

但是,即使有mmap()调用,我仍然偶尔会看到进程在执行上述操作时被 OOM-killer 杀死。

我的问题是,我是否对 Linux 在同时存在大型 mmap() 和有限 RAM 的情况下的行为过于乐观?(即 mmap()-ing 一个 200MB 的文件,然后读/写到 mmap() 的内存仍然需要 200MB 的可用 RAM 才能可靠地完成?)或者 mmap() 是否应该足够聪明以分页出 mmap 的页面当内存不足时,但我在使用它时做错了什么?

FWIW我做映射的代码在这里:

void FixedSizeDataBuffer :: TryMapToFile(const std::string & filePath, bool createIfNotPresent, bool autoDelete)
{
   const int fd = open(filePath.c_str(), (createIfNotPresent?(O_CREAT|O_EXCL|O_RDWR):O_RDONLY)|O_CLOEXEC, S_IRUSR|(createIfNotPresent?S_IWUSR:0));
   if (fd >= 0)
   {
      if ((autoDelete == false)||(unlink(filePath.c_str()) == 0))  // so the …
Run Code Online (Sandbox Code Playgroud)

linux mmap out-of-memory

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

有没有自动化的方法来实现post-constructor和pre-destructor虚方法调用?

由于从构造函数和析构函数内部调用虚方法的众所周知的问题,我通常最终会得到一些类,这些类需要在构造函数之后调用最终设置方法,并且在它们之前调用一个预拆解方法析构函数,像这样:

MyObject * obj = new MyObject;
obj->Initialize();   // virtual method call, required after ctor for (obj) to run properly
[...]
obj->AboutToDelete();  // virtual method call, required before dtor for (obj) to clean up properly
delete obj;
Run Code Online (Sandbox Code Playgroud)

这有效,但它带来了调用者在适当的时候忘记调用其中一种或两种方法的风险.

所以问题是:在C++中是否有任何方法可以自动调用这些方法,因此调用者不必记得调用它们?(我猜不会有,但我想我无论如何都会问,以防有一些聪明的方法去做)

c++ methods virtual-destructor

13
推荐指数
2
解决办法
4461
查看次数

对堆的访问是否已序列化?

每个程序员都会很快了解多线程的一条规则是:

如果一个以上的线程可以访问一个数据结构,并且至少有一个线程可以修改该数据结构,那么最好将对该数据结构的所有访问序列化,否则您将陷入调试的困境

通常,此序列化是通过互斥锁完成的-即,要读取或写入数据结构的线程将锁定互斥锁,执行所需的任何操作,然后解锁互斥锁以使其可再次用于其他线程。

这使我明白了:进程的内存堆是一个可由多个线程访问的数据结构。这是否意味着每次调用默认/非过载newdelete通过过程全局互斥锁序列化,因此是一个潜在的序列化瓶颈,可以减缓多线程程序?还是现代堆实现以某种方式避免或减轻了该问题,如果是,那么它们如何实现?

(注意:我正在为这个问题linux加上标签,以避免做出正确但不具信息性的“依赖于实现的响应”,但是我也想听听Windows和MacOS / X如何做到这一点,如果有的话实施之间的重大差异)

c++ linux heap multithreading

13
推荐指数
2
解决办法
239
查看次数