小编Geo*_*son的帖子

使用继承的类模板避免公共成员不可见性和源代码膨胀/重复的更好方法是什么?

上下文:
受保护和公共类成员的继承是面向对象编程的基本概念.下面的简单示例说明了一个经常遇到的情况,其中类CDerived继承了类的所有公共成员,CBase并添加了自己的1个附加函数,而不更改或显式重新定义或重新定义类的任何公共成员CBase.

#include <stdio.h>

class CBase
{
public:
    char Arr[32];

    int Fn1(void) {
        return Arr[1] ^ Arr[sizeof(Arr)-1];
    }

    int Fn2(void) {
        return Arr[2] ^ Arr[sizeof(Arr)-2];
    }
};


class CDerived : public CBase
{
public:  
    int FnSum(void) {
        return Fn1() + Fn2();
    }
};

int main(void)
{
    CDerived ddd;

    printf("%d\n", ddd.Fn1());
    printf("%d\n", ddd.Fn2());
    printf("%d\n", ddd.FnSum());

    return (int)ddd.Arr[0];
};
Run Code Online (Sandbox Code Playgroud)

上面的代码在所有主要编译器上编译都没有问题.

但是,如果希望" 模板化 "此代码,例如:通过参数化Arr数组的大小,那么CBase类模板的所有公共成员对CDerived符合最新C++标准的编译器上的类模板都是不可见的.
以下是问题代码:

#include <stdio.h>

template …
Run Code Online (Sandbox Code Playgroud)

c++ templates

21
推荐指数
2
解决办法
795
查看次数

在R值中使用volatile两次

该声明:

volatile unsigned char * volatile p = (volatile unsigned char * volatile)v;
Run Code Online (Sandbox Code Playgroud)

在MSVC v14.1中生成警告C4197:

警告C4197:'volatile unsigned char*volatile':忽略强制转换中的顶级volatile

2011 C标准([N1570] 6.7.3 4.)规定:"与限定类型相关联的属性仅对表达式有意义,即l值",因此此投射中的顶级volatile将被忽略并生成这个警告.

该代码的作者指出,它不违反C标准,并且需要阻止一些GCC优化.他通过以下代码说明了代码的问题:https://godbolt.org/g/xP4eGz

#include <stddef.h>

static void memset_s(void * v, size_t n) {
  volatile unsigned char * p = (volatile unsigned char *)v;
  for(size_t i = 0; i < n; ++i) {
    p[i] = 0;
  }
}

void f1() {
  unsigned char x[4];
  memset_s(x, sizeof x);
}

static void memset_s_volatile_pnt(void * v, size_t n) {
  volatile unsigned …
Run Code Online (Sandbox Code Playgroud)

c c++ gcc visual-c++

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

Non-recursive enumeration of triply restricted positive integer compositions

After creating an iterative (non-recursive) function, that enumerates doubly restricted compositions of positive integers in a lexicographic order, for a microcontroller with a very small amount of RAM (but large EPROM), I had to expand the number of restrictions to 3, namely to:

  1. The restriction on the length of the composition
  2. The restriction on the the minimum value of elements
  3. The restriction on the the maximum value of elements

The original function, that generates the doubly restricted compositions is listed …

c++ algorithm combinatorics

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

在 makefile 中将 Windows 路径转换为 ​​Unix 路径

这个问题与Convert Cygwin path to Windows path in a makefile有关,但并不相同。

我需要转换 Windows 路径,例如:

C:\src\bin
Run Code Online (Sandbox Code Playgroud)

进入 Unix 路径,例如:

/c/src/bin
Run Code Online (Sandbox Code Playgroud)

在 makefile 中,我可以使用以下代码来转换此类路径:

slashedpath = $(subst \\,\/,$(windowspath))
unixpath = $(shell cygpath -u $(slashedpath))
Run Code Online (Sandbox Code Playgroud)

当cygpath函数不可用时,如何在 GNU Make 正在处理的 makefile 中执行相同的转换?

ps 如果$(windowspath)包含多个路径怎么办?如何将它们全部转换?

makefile gnu-make

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

如何指示MSVC编译器使用64位/ 32位除法而不是较慢的128位/ 64位除法?

我如何告诉MSVC编译器使用64位/ 32位除法运算来为x86-64目标计算以下函数的结果:

#include <stdint.h> 

uint32_t ScaledDiv(uint32_t a, uint32_t b) 
{
  if (a > b)
        return ((uint64_t)b<<32) / a;   //Yes, this must be casted because the result of b<<32 is undefined
  else
        return uint32_t(-1);
}
Run Code Online (Sandbox Code Playgroud)

我希望代码在if语句为true时编译为使用64位/ 32位除法运算,例如:

; Assume arguments on entry are: Dividend in EDX, Divisor in ECX
mov edx, edx  ;A dummy instruction to indicate that the dividend is already where it is supposed to be
xor eax,eax
div ecx   ; EAX = EDX:EAX / ECX
Run Code Online (Sandbox Code Playgroud)

...但是x64 …

c x86-64 integer-division compiler-optimization visual-c++

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

诱导GCC发出REPE CMPSB

如何哄骗GCC编译器在普通C中发出REPE CMPSB指令,而没有"asm"和"_emit"关键字,调用包含的库和编译器内在函数?

我尝试了一些像下面列出的C代码,但没有成功:

unsigned int repe_cmpsb(unsigned char *esi, unsigned char *edi, unsigned int ecx) {

    for (; ((*esi == *edi) && (ecx != 0)); esi++, edi++, ecx--); 

    return ecx;
}
Run Code Online (Sandbox Code Playgroud)

请参阅GCC如何在此链接上编译它:https:
//godbolt.org/g/obJbpq

PS
我意识到无法保证编译器以某种方式编译C代码,但我还是想哄它以获得乐趣,只是为了看它有多聪明.

c performance x86 assembly gcc

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

在某些情况下,在x86-64 Intel / AMD CPU上,128bit / 64bit硬件无符号除法能否比64bit / 32bit除法更快?

可以通过硬件128bit / 64bit除法指令执行缩放的64bit / 32bit除法,例如:

; Entry arguments: Dividend in EAX, Divisor in EBX
shl rax, 32  ;Scale up the Dividend by 2^32
xor rdx,rdx
and rbx, 0xFFFFFFFF  ;Clear any garbage that might have been in the upper half of RBX
div rbx  ; RAX = RDX:RAX / RBX
Run Code Online (Sandbox Code Playgroud)

...在某些特殊情况下,比硬件64位/ 32位除法指令执行的缩放64位/ 32位除法更快,例如:

; Entry arguments: Dividend in EAX, Divisor in EBX
mov edx,eax  ;Scale up the Dividend by 2^32
xor eax,eax
div ebx  ; EAX = EDX:EAX / EBX
Run Code Online (Sandbox Code Playgroud)

“某些特殊情况”是指异常的红利和除数。我只想比较 …

performance x86 assembly x86-64 integer-division

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

如何更紧凑地初始化和返回向量的向量?

如何更紧凑地初始化和返回向量的向量?下面的代码看起来臃肿,重复的两种情况时,K==1K==N

std::vector< std::vector<unsigned int> > Foobar(const unsigned int K, const unsigned int N)
{
    std::vector< std::vector<unsigned int> > res;

    if (K == 1)
    {
        std::vector<unsigned int> r(1,N);  //One N.
        res.emplace_back(r);
        return res;
    }

    if (K == N)
    {
        std::vector<unsigned int> r(N,1);  //N ones.
        res.emplace_back(r);
        return res;
    }

    PopulateVectors(res, K+1, N+1);
    PopulateVectors(res, K, N);
    return res;
}
Run Code Online (Sandbox Code Playgroud)

该函数PopulateVectors()接受res作为引用并将多个向量插入其中。它内部的工作方式对这个问题无关紧要。

c++

0
推荐指数
1
解决办法
53
查看次数