小编Bee*_*ope的帖子

我可以避免在一系列函数调用中使用模板消歧器吗?

我有一个模板构建器/工厂类,它使对象成为类型Foo,其中make()方法是模板方法,如下所示:

template<typename T1>
class FooMaker
{
  template<typename T2>
  Foo make(...) { ... }
};
Run Code Online (Sandbox Code Playgroud)

这里的想法T1是绑定到构建器,因为它对于所有make()调用都是相同的,而T2(对于每个调用,它总是一个函数名)通常是不同的make().

make()多次调用创建不同类型的对象,模板类和模板函数的组合意味着我必须template在每次调用之前使用消歧器:

template <typename MAKER_T>
void make_some_foos()
{
    auto maker = FooMaker<MAKER_T>(...);
    Foo foo1 = maker.template make<Type1>(...);
    Foo foo2 = maker.template make<Type2>(...);
    // etc...
}
Run Code Online (Sandbox Code Playgroud)

我想template在构造Foo上面的每一行上都需要关键字.一般来说,我make()对每个FooMaker对象都有很多调用,因此在创建工厂时会有少量额外的代码.

显然,我可以做到这一点使用它可以隐藏宏template细节,但有一个良好的非宏解决方案1


1我能够继续前进T1,并T2在同一水平-使它们既类模板参数,或两者功能模板参数,但前者需要一个不同的制造商为每一个新的类型T2,而后者的手段冗余指定相同的T1 …

c++ templates c++11

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

什么是函数typedef的使用等价物?

如何使用new 1 using关键字声明函数类型?

我知道如何使用它来声明函数指针类型.例如,以下typedef:

typedef int (*int_to_int)(int);
Run Code Online (Sandbox Code Playgroud)

似乎等同于以下使用声明:

using int_to_int = int (*)(int);
Run Code Online (Sandbox Code Playgroud)

如何对以下非指针typedef执行相同操作:

typedef int (int_to_intf)(int);
Run Code Online (Sandbox Code Playgroud)

我的"删除typedef名称并将其放在using"算法后不起作用:

using int_to_intf_u = int ()(int);  // nope, doesn't compile
Run Code Online (Sandbox Code Playgroud)

一个goldbolt链接.


1至少对于像我这样仍然将"新"定义为"在C++ 11中引入"的可怜灵魂.

c++ using-declaration c++11

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

在内联汇编中使用特定的 zmm 寄存器

我可以告诉gcc 风格的内联汇编将我的__m512i变量放入特定的 zmm寄存器中,例如zmm31

x86 assembly gcc inline-assembly

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

是否保证字节方式的零 int 是零的表示?

特别是,assert保证以下内容成立:

int i;
memset(&i, 0, sizeof(int));
assert(i == 0);
Run Code Online (Sandbox Code Playgroud)

c++

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

GCC 编译器中的条件移动 (cmov)

我在某处看到 GCC 编译器有时更喜欢在将我的代码转换为 ASM 时不使用条件 mov。

在什么情况下它可能会选择做条件 mov 以外的事情?

c assembly gcc compiler-optimization

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

可变参数模板的无递归扩展到数组访问

考虑以下非类型可变参数模板函数:

template <typename dummy = void>
void write_at_offsets(volatile char *p) {
}

template <size_t OFF, size_t... OFFs>
void write_at_offsets(volatile char *p) {
    p[OFF] = 1;
    write_at_offsets<OFFs...>(p);
}
Run Code Online (Sandbox Code Playgroud)

它使用递归方法在模板参数包中指定的偏移量处写入 1。

这是否可以在 C++11 中不使用递归而简洁地编写,例如,通过一次性扩展整个包?

c++ variadic-templates c++11

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

上下文管理器的“打开工作”应该发生在 __init__ 还是 __enter__ 中?

我找到了下面的例子以下对象上下文管理器的File

\n
class File(object):\n    def __init__(self, file_name, method):\n        self.file_obj = open(file_name, method)\n    def __enter__(self):\n        return self.file_obj\n    def __exit__(self, type, value, traceback):\n        self.file_obj.close()\n
Run Code Online (Sandbox Code Playgroud)\n

在这里,管理器完成的工作(实际上是打开文件)发生在该__init__方法中。然而,在随附的文本中,他们建议文件打开应该发生在__enter__

\n
\n

让\xe2\x80\x99s 谈谈幕后发生的事情。

\n
    \n
  1. with 语句存储退出File类的
  2. \n
  3. 它调用输入File 类的
  4. \n
  5. 进入打开文件并返回它。
  6. \n
  7. 打开的文件句柄被传递给opened_file。
  8. \n
  9. 我们使用 .write() 写入文件。
  10. \n
  11. with 语句调用存储的退出方法。
  12. \n
  13. 出口关闭文件。
  14. \n
\n
\n

一般来说,哪种方法是正确的?似乎撤销的工作__exit__应该发生在__enter__,而不是__init__因为它们是通过上下文管理器机制 1:1 配对的,但这个例子让我感到怀疑。 …

python contextmanager

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

我可以在 Java 中同时迭代两个数组吗?

对于一个数组,我可以这样迭代:

for(String str:myStringArray){

}
Run Code Online (Sandbox Code Playgroud)

如何同时迭代两个数组?因为我确信这两个的长度是相等的。我想要如下所示:

for(String attr,attrValue:attrs,attrsValue) {

}
Run Code Online (Sandbox Code Playgroud)

但这是错误的。

在这种情况下,也许映射是一个不错的选择,但是 3 个等长数组怎么样?我只是讨厌创建索引“int i”,它按以下格式使用:

for(int i=0;i<length;i++){
}
Run Code Online (Sandbox Code Playgroud)

java arrays

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

将缓冲区对齐到N字节边界但不是2N字节边界?

我想分配一些char缓冲区0,以传递给具有特定对齐要求的外部非C++函数.

的要求是,该缓冲器被对齐到N字节1边界,但2N边界.例如,如果N是64,则指向此缓冲区的指针p应满足((uintptr_t)p) % 64 == 0并且((uintptr_t)p) % 128 != 0- 至少在指针具有通常解释的平台上作为转换时的普通地址uintptr_t.

有没有合理的方法来使用C++ 11的标准工具?

如果没有,是否有合理的方法在标准设施2之外执行此操作,这在现代编译器和平台的实践中有效?

缓冲区将传递给外部例程(遵守C ABI但以asm编写).所需的对齐通常大于16,但小于8192.

过度分配或任何其他轻微的资源浪费问题都是完全正确的.我对正确性和可移植性比对浪费几个字节或毫秒更感兴趣.

在堆和堆栈上都能正常工作的东西是理想的,但任何可用的东西仍然相当不错(优先考虑堆分配).


0这可能是用operator new[]malloc或者是一些其他的方法是对准感知:什么是有意义的.

1像往常一样,N是两个人的力量.

2是的,我理解这种类型的答案会导致语言律师变得中风,所以如果你只是忽略了这一部分.

c++ assembly c++11

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

为什么在这个被破坏的std :: string dtor中有锁定的xadd指令?

我有一个非常简单的代码:

#include <string>
#include <iostream>

int main() {
    std::string s("abc");
    std::cout << s;
}
Run Code Online (Sandbox Code Playgroud)

然后,我编译了它:

g++ -Wall test_string.cpp -o test_string -std=c++17 -O3 -g3 -ggdb3
Run Code Online (Sandbox Code Playgroud)

然后将其反编译,最有趣的部分是:

00000000004009a0 <_ZNSs4_Rep10_M_disposeERKSaIcE.isra.10>:
  4009a0:       48 81 ff a0 11 60 00    cmp    rdi,0x6011a0
  4009a7:       75 01                   jne    4009aa <_ZNSs4_Rep10_M_disposeERKSaIcE.isra.10+0xa>
  4009a9:       c3                      ret    
  4009aa:       b8 00 00 00 00          mov    eax,0x0
  4009af:       48 85 c0                test   rax,rax
  4009b2:       74 11                   je     4009c5 <_ZNSs4_Rep10_M_disposeERKSaIcE.isra.10+0x25>
  4009b4:       83 c8 ff                or     eax,0xffffffff
  4009b7:       f0 0f c1 47 10          lock xadd …
Run Code Online (Sandbox Code Playgroud)

c++ assembly gcc x86-64 atomic

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