我有一个带有模板参数的类,它应该决定它包含哪两种数据样式.基于该参数,我想以两种不同的方式实现成员函数.我尝试使用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)
这就是为什么我把伪参数放在那里 …
在系统编程中,通常会调用某些可能失败的库函数,如果失败,则检查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)
我认为这有一些建议:
如果之前没有考虑到这一点,我会感到惊讶,所以我会接受任何过去或未决提案的链接.我也接受一个答案,解释为什么上面会引入现有语言的任何问题(Python 3.x,因为我认为2.x主要是冻结的).
我有一个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.
我得到了一个 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.
我试过类似的东西 …
可以/如何使用谷物库序列化数组.
即
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,我想要一个二进制存档.
我有一个复杂的程序,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) 从上一个问题的接受答案中,我发现了一条我不知道的关于模板和格式良好的规则
如果出现以下情况,则程序格式错误,无需诊断:
- [...]
- 可变参数模板的每个有效特化都需要一个空模板参数包,或者
- [...]
根据这条规则(如果我理解正确的话),以下模板函数的格式不正确
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) 发送UDP多播时,您可以使用IP_MULTICAST_TTL设置TTL.但否则你会用IP_TTL.为什么这两种不同的选择在setsockopt()和getsockopt()?是否有任何情况下单独设置它们是否有意义?
在我看来,他们最终在IP头中设置了相同的值.
在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++ 代码:
#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)