Tag: 语言律师

什么时候应该使用@classmethod和def方法(self)?

在集成一个我以前没有用过的Django应用程序的时候,我发现了两种不同的用于在类中定义函数的方法。 作者似乎非常有意地使用它们。 第一个是我自己用的很多: class Dummy(object): def some_function(self,*args,**kwargs): do something here self is the class instance 另一个是我不使用的,主要是因为我不明白什么时候使用它,以及为什么: class Dummy(object): @classmethod def some_function(cls,*args,**kwargs): do something here cls refers to what? 在Python文档中, classmethod装饰classmethod这句话来解释: 类方法将类作为隐式第一个参数接收,就像实例方法接收实例一样。 所以我想cls是指Dummy本身( class ,而不是实例)。 我不完全明白为什么会这样,因为我总是可以这样做: type(self).do_something_with_the_class 这只是为了清楚起见,还是我错过了最重要的部分:没有它的事情是不可能做到的令人着迷和迷人的事情?

在C ++中声明

据我所知,C ++中的声明/初始化是带有“基本types”的语句,后面跟着逗号分隔的声明列表。 考虑下面的声明: int i = 0, *const p = &i; // Legal, the so-called base type is 'int'. // i is an int while p is a const pointer to an int. int j = 0, const c = 2; // Error: C++ requires a type specifier for all declarations. // Intention was to […]

取数组地址时的不同指针的算术结果

程序: #include<stdio.h> int main(void) { int x[4]; printf("%p\n", x); printf("%p\n", x + 1); printf("%p\n", &x); printf("%p\n", &x + 1); } 输出: $ ./a.out 0xbff93510 0xbff93514 0xbff93510 0xbff93520 $ 我期望以下是上述程序的输出。 例如: x // 0x100 x+1 // 0x104 Because x is an integer array &x // 0x100 Address of array &x+1 // 0x104 但是最后一个陈述的结果与我预期的不一样。 &x也是数组的地址。 因此,递增1将打印地址递增4.但是&x+1给出地址递增10.为什么?

sizeof(void())是一个合法的expression式吗?

从[5.3.3 / 1]中我发现: sizeof运算符不能应用于具有函数或不完整types的expression式 从[3.9 / 5]我发现: 不完全定义的对象types和cv void是不完整的types 无论如何, sizeof不评估它的操作数,我会说sizeof(void())是一个合法的expression式(实际上GCC编译它,结果是1)。 另一方面,从这里开始 ,在讨论sizeof ,没有提到void , 在提到size 1的types时,也没有提到具有实现定义大小的types的列表。 问题是: sizeof(void())是一个合法的expression式吗? 它保证有大小等于1? 或者这是一个导致UB的法律expression,这就是全部?

“长”保证至less有32位?

通过阅读C ++标准,我一直认识到C ++中积分基本types的大小如下: sizeof(char) <= sizeof(short int) <= sizeof(int) <= sizeof(long int) 我从3.9.1 / 2推导出来的: 有四个有符号整数types:“signed char”,“short int”,“int”和“long int”。在这个列表中,每个types至less提供与列表中的前一个types相同的存储。 Plain int具有执行环境的体系结构所build议的自然大小 此外, char的大小被3.9.1 /描述为: 足够大以存储实现的基本字符集的任何成员。 1.7 / 1从更具体的angular度对此进行了定义: C + +内存模型中的基本存储单元是字节。 一个字节至less足够大以包含基本执行字符集的任何成员,并且由一个连续的位序列组成,其数目是由实现定义的。 这使我得出以下结论: 1 == sizeof(char) <= sizeof(short int) <= sizeof(int) <= sizeof(long int) sizeof告诉我们这个types有多less个字节。 而且,实现定义了多less位在一个字节中。 我们中的大多数人可能习惯于处理8位字节,但标准中说有一个字节有n位。 在这篇文章中 ,Alf P. Steinbach说: 长保证(至less)32位。 这在一切我都了解的基础types的大小在C ++根据标准的苍蝇。 通常情况下,我只是将这个陈述折扣为初学者是错误的,但是因为这是Alf,我决定进一步调查。 […]

如果没有新的成员variables与基类相比,C ++是否允许增加派生类的大小?

假设我有一个基类,有一些成员variables,没有虚函数: class Base { int member; }; 以及一个派生类,它以非虚方式从Base派生,并且没有新的成员variables,也没有虚函数: class Derived : Base { }; 显然, sizeof(Derived)不能小于sizeof(Base) 。 sizeof(Derived)需要等于sizeof(Base) ?

char *和std :: uint8_t之间的reinterpret_cast * – 安全吗?

现在我们都有时需要使用二进制数据。 在C ++中,我们使用字节序列,并且从开始的char是我们的构build块。 定义为sizeof为1,它是字节。 所有的库I / O函数都默认使用char 。 一切都很好,但总是有一点担心,有点怪异的人,一些字节的位数是由实现定义的。 所以在C99中,决定引入几个typedef来让开发人员很容易expression自己的固定宽度的整数types。 可选,当然,因为我们从不想伤害可移植性。 其中, uint8_t作为std::uint8_t (一种固定宽度的8位无符号整数types)迁移到C ++ 11中,对于真正想要使用8位字节的人来说,是最佳select。 因此,开发人员接受了新的工具,并开始构build一些库,表示他们接受8位字节序列,如std::uint8_t* , std::vector<std::uint8_t>或其他。 但是,也许有一个非常深刻的想法,标准化委员会决定不要求实施std::char_traits<std::uint8_t>因此禁止开发人员轻松地实例化std::basic_fstream<std::uint8_t>和轻松读取std::uint8_t s作为二进制数据。 或者,也许,我们中的一些人不关心一个字节的位数,并且对它感到满意。 但不幸的是,两个世界相互碰撞,有时你必须把数据作为char*传递给期望std::uint8_t*的库。 但是,等等,你说,不是charvariables位和std::uint8_t固定为8? 会导致数据丢失吗? 那么这个呢有一个有趣的Standardese。 被定义为char字节和字节是最小的可寻址内存块,所以不能有比char小的位宽的types。 接下来,它被定义为能够保存UTF-8代码单元。 这给我们至less8位。 所以现在我们有一个typedef,它需要8位宽,至less8位宽的types。 但是有其他的select吗? 是的, unsigned char 。 请记住, char签名是实现定义的。 任何其他types? 谢天谢地,不。 所有其他整数types的要求范围不在8位。 最后, std::uint8_t是可选的,这意味着使用这种types的库如果没有定义就不会编译。 但是如果编译呢? 我可以很有把握地说,这意味着我们在一个8位字节和CHAR_BIT == 8 。 一旦我们有了这个知识,我们有8位字节, std::uint8_t被实现为char或unsigned char ,我们可以假设我们可以从char*执行reinterpret_cast到std::uint8_t* ,反之亦然? 它是否便携? 这是我的Standardese阅读技能使我失望的地方。 我读了安全派生的指针( […]

在cpp.react库的C ++源代码中奇怪的“ – > * ”expression式

这里是我在cpp.react库的文档中find的C ++代码片段: auto in = D::MakeVar(0); auto op1 = in ->* [] (int in) { int result = in /* Costly operation #1 */; return result; }; 我从来没有见过->* []符号。 首先,我认为这只是一个错字,但我也在源代码中find了这样一个expression式: auto volume = (width,height,depth) ->* [] (int w, int h, int d) { return w * h * d; }; 这是有效的C + + 11(或C + […]

Boost.Spirit使用这个不寻常的C ++模板特性的名字是什么?

下面的代码来自Boost.Spirit x3文档 。 它使用了我以前从未见过的有趣的C ++语法,在不知道正确的术语的情况下几乎不可能在search查询中进行描述。 这是一个class的前进宣言的简写吗? C ++标准中提到的这个特性在哪里? namespace parser { using x3::eps; using x3::lit; using x3::_val; using x3::_attr; using ascii::char_; auto set_zero = [&](auto& ctx){ _val(ctx) = 0; }; auto add1000 = [&](auto& ctx){ _val(ctx) += 1000; }; auto add = [&](auto& ctx){ _val(ctx) += _attr(ctx); }; // What is this? This is the […]

新的字符实际上保证alignment的内存类types?

通过new char[sizeof(T)]分配一个缓冲区,保证为Ttypes正确地分配内存,其中T所有成员都有自然的,实现定义的alignment方式(也就是说,你还没有使用alignas关键字修改它们的alignment)。 我在这里看到了几个答案中的这个保证,但是我不完全清楚标准是如何得到这个保证的。 该标准的5.3.4-10给出了基本要求:基本上new char[]必须与max_align_talignment。 我所缺less的是说, alignof(T)将始终是一个有效的队列,最大值为max_align_t 。 我的意思是,这似乎很明显,但一个结构的结果alignment最多是max_align_t ? 甚至连点3.11-3都说可以支持扩展alignment,所以编译器可以自己决定一个类是否是一个过度alignment的types?