小编Joh*_*nck的帖子

基于类模板参数的Specialize C++成员函数

我有一个带有模板参数的类,它应该决定它包含哪两种数据样式.基于该参数,我想以两种不同的方式实现成员函数.我尝试使用Boost Enable-If,但没有成功.这是我最惊讶的代码版本不起作用:

#include <boost/utility/enable_if.hpp>
enum PadSide { Left, Right };
template <int> struct dummy { dummy(int) {} };

template <PadSide Pad>
struct String
{
    typename boost::enable_if_c<Pad ==  Left, void>::type
        getRange(dummy<0> = 0) {}
    typename boost::enable_if_c<Pad == Right, void>::type
        getRange(dummy<1> = 0) {}
};

int main()
{
    String<Left> field;
    field.getRange();
}
Run Code Online (Sandbox Code Playgroud)

为此,g ++ 4.6.0说:

no type named ‘type’ in ‘struct boost::enable_if_c<false, void>’
Run Code Online (Sandbox Code Playgroud)

当然,第二次重载应该不起作用,但是由于SFINAE,它应该被忽略.如果我删除虚函数参数,g ++会这样说:

‘typename boost::enable_if_c<(Pad == Right), void>::type
    String<Pad>::getRange()‘
cannot be overloaded with
‘typename boost::enable_if_c<(Pad == Left), void>::type
    String<Pad>::getRange()‘
Run Code Online (Sandbox Code Playgroud)

这就是为什么我把伪参数放在那里 …

c++ templates boost overloading enable-if

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

是否有针对条件"除"块的Python提议?

在系统编程中,通常会调用某些可能失败的库函数,如果失败,则检查errno确切原因.即使在Python中也是如此,我认为它比它需要的更麻烦.让我们以一些试图删除文件的代码为例,如果文件不存在则继续静默:

try:
    sftp.unlink(path)
except IOError as ex:
    if ex.errno != errno.ENOENT:
        raise
Run Code Online (Sandbox Code Playgroud)

我想知道在Python中是否曾经允许或建议它做更像这样的事情:

try:
    sftp.unlink(path)
except IOError as ex if ex.errno == errno.ENOENT:
    pass
Run Code Online (Sandbox Code Playgroud)

我认为这有一些建议:

  1. 更简洁.
  2. 熟悉:因为我们已经可以捕获某些类型的异常,所以我们只捕获某些实际情况.未捕获的异常以通常的方式传播.
  3. 不需要新关键字,也不需要任何主要的新语法结构.

如果之前没有考虑到这一点,我会感到惊讶,所以我会接受任何过去或未决提案的链接.我也接受一个答案,解释为什么上面会引入现有语言的任何问题(Python 3.x,因为我认为2.x主要是冻结的).

python exception-handling exception pep python-3.x

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

C++ 11基于范围的循环:如何忽略值?

我有一个C++容器,我想运行一个循环的次数与该容器中的元素相同.但我不关心循环期间容器中的值.例如:

for (const auto& dummy : input) {
    cout << '.';
}
Run Code Online (Sandbox Code Playgroud)

唯一的问题是,dummy是一个未使用的变量,我已指示编译器禁止这些.

我提出的两个不优雅的解决方案是(void)dummy;在循环体中说要使编译器静音,或者使用从0到0的旧式for循环distance(begin(input), end(input)).

我尝试省略变量名但无法编译(没什么大惊喜).

我正在使用GCC 4.7.2.

c++ for-loop c++11

5
推荐指数
2
解决办法
1666
查看次数

如何参数化生成文件目标

我得到了一个 Makefile,它确实构建了一个 32 位和 64 位版本的项目:

#############################
# 32 bit variant of test tool
#############################
hidtest_32: $(OBJS_32)
    $(CXX_32) -m32 -g $^ $(LIBS) -o hidtest_32

hid_32.o: hid.c
    $(CC_32) -m32 $(CFLAGS) $< -o hid_32.o

../hidtest/hidtest_32.o: ../hidtest/hidtest.cpp
    $(CC_32) -m32 $(CFLAGS) $< -o ../hidtest/hidtest_32.o


#############################
# 64 bit variant of test tool
#############################
hidtest_64: $(OBJS_64)
    $(CXX_64) -m64 -g $^ $(LIBS) -o hidtest_64

hid_64.o: hid.c
    $(CC_64) -m64 $(CFLAGS) $< -o hid_64.o

../hidtest/hidtest_64.o: ../hidtest/hidtest.cpp
    $(CC_64) -m64 $(CFLAGS) $< -o ../hidtest/hidtest_64.o
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,两种变体都使用完全相同的构建过程,只是编号32已替换为64.

我试过类似的东西 …

makefile

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

C++ Cereal:序列化C风格的数组

可以/如何使用谷物库序列化数组.

void save(Archive & ar, const unsigned int version) const
{
    unsigned int l  = g1_size_bin(g,POINT_COMPRESS);
    uint8_t data[l];
    memset(data, 0, l);
    g1_write_bin(data, l, g,POINT_COMPRESS);
    ar(l);
    ar(data); // what should be here
}
Run Code Online (Sandbox Code Playgroud)

这不起作用(我也不期望它).也没有

ar(cereal::binary_data(data,l)); 
Run Code Online (Sandbox Code Playgroud)

(我认为它会工作,因为它看起来像一个人会使用的增强代码),这会产生编译错误:

/usr/local/include/cereal/cereal.hpp:79:17:注意:候选模板被忽略:替换失败:可变修改类型'unsigned char(&)[l]'不能用作模板参数BinaryData binary_data(T && data,size_t size)

也没有

ar.saveBinaryValue(data,l);
Run Code Online (Sandbox Code Playgroud)

由于该方法似乎只支持XML/Json,我想要一个二进制存档.

c++ cereal

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

GCC有时不会内联std :: array :: operator []

我有一个复杂的程序,std::array<double, N>它使用N的小值.它用于operator[]从这些数组中获取值.

我发现GCC 6.1有-O2-O3没有内联这些调用,导致这些C++数组比它们的C等价物慢.

这是生成的程序集:

340 <std::array<double, 8ul>::operator[](unsigned long) const>:

340:  48 8d 04 f7             lea    (%rdi,%rsi,8),%rax
344:  c3                      retq   
345:  90                      nop
346:  66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
34d:  00 00 00 
Run Code Online (Sandbox Code Playgroud)

为每个大小的数组发出相同的代码(因为没有边界检查).

这样一个数组的循环如下所示:

4c0:  e8 7b fe ff ff          callq  340 <std::array<double, 8ul>::operator[](unsigned long) const>
4c5:  be 07 00 00 00          mov    $0x7,%esi
4ca:  4c 89 f7                mov    %r14,%rdi
4cd:  48 89 44 24 78          mov …
Run Code Online (Sandbox Code Playgroud)

c++ optimization gcc inline c++11

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

模板、良好成型性和零包装长度规则

从上一个问题的接受答案中,我发现了一条我不知道的关于模板和格式良好的规则

如果出现以下情况,则程序格式错误,无需诊断:

  • [...]
  • 可变参数模板的每个有效特化都需要一个空模板参数包,或者
  • [...]

根据这条规则(如果我理解正确的话),以下模板函数的格式不正确

template <typename ... Ts>
int foo (std::tuple<Ts...> const &)
 { return std::get<sizeof...(Ts)>(std::tuple<int>{42}); }
Run Code Online (Sandbox Code Playgroud)

因为唯一有效的专业化需要和空Ts...参数包。

但是(也许是因为我不太懂英语)在模板具有两个以上参数包的情况下,我不确定是否理解这条规则。

我的意思是......以下foo()功能

#include <tuple>
#include <iostream>

template <typename ... Ts, typename ... Us>
int foo (std::tuple<Ts...> const &, std::tuple<Us...> const &)
 { return std::get<sizeof...(Ts)+sizeof...(Us)-1U>(std::tuple<int>{42}); }

int main ()
 {
   auto t0 = std::tuple<>{};
   auto t1 = std::tuple<int>{0};

   //std::cout << foo(t0, t0) << std::endl; // compilation error
   std::cout << foo(t0, t1) << std::endl;   // print …
Run Code Online (Sandbox Code Playgroud)

c++ well-formed language-lawyer variadic-templates c++11

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

为什么IP_TTL和IP_MULTICAST_TTL是单独的套接字选项?

发送UDP多播时,您可以使用IP_MULTICAST_TTL设置TTL.但否则你会用IP_TTL.为什么这两种不同的选择在setsockopt()getsockopt()?是否有任何情况下单独设置它们是否有意义?

在我看来,他们最终在IP头中设置了相同的值.

c sockets multicast ttl setsockopt

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

Valgrind在C++代码中显示意外输出

在C++代码的开头,我初始化一个1000000(百万)bool类型数据的向量.但是,在valgrind中,最大堆+堆栈使用量显示为200Kb.鉴于Bool是1字节,不应该是1 Mb?

有没有我没有意识到的优化?或者我错过了什么?

谢谢你的提前.

我使用的是Ubuntu64 16.04系统.编译没有-O参数的代码.

编辑:代码可以简化为此,

vector<bool> * isPrime;
int main(){
    isPrime = new vector<bool>(1000000, true);
}
Run Code Online (Sandbox Code Playgroud)

编辑2:似乎有一个我没有意识到的优化(在评论中说明).谢谢.

c++ memory valgrind stdvector c++11

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

如果没有 -fwrapv,GCC 将不会使用自己的优化技巧

考虑这个 C++ 代码:

#include <cstdint>

// returns a if less than b or if b is INT32_MIN
int32_t special_min(int32_t a, int32_t b)
{
    return a < b || b == INT32_MIN ? a : b;
}
Run Code Online (Sandbox Code Playgroud)

GCC-fwrapv正确地认识到减去 1b可以消除特殊情况,并为 x86-64 生成以下代码

    lea     edx, [rsi-1]
    mov     eax, edi
    cmp     edi, edx
    cmovg   eax, esi
    ret
Run Code Online (Sandbox Code Playgroud)

但如果没有-fwrapv它,会生成更糟糕的代码:

    mov     eax, esi
    cmp     edi, esi
    jl      .L4
    cmp     esi, -2147483648
    je      .L4
    ret
.L4:
    mov     eax, edi …
Run Code Online (Sandbox Code Playgroud)

c++ optimization gcc x86-64 compiler-optimization

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