在json字符串中是否忽略空格,制表符和回车符等空白字符?
例如,{"a":"b"}
等于{"a" : "b"}
?
我最近在这个问题上跌跌撞撞
for(int i=0,n=v.size(); i<n; i++) {
...
P2d n = ... <<<--- error here
}
Run Code Online (Sandbox Code Playgroud)
编译器抱怨n
已经定义了局部变量的事实,尽管open括号看起来应该开始一个新的范围.
事实上,该标准对此有一个特殊的措辞,虽然使用g ++ 4.6.3编译好的代码,它抱怨更新的版本和其他编译器.
这条特殊规则背后的理由是什么(如果有的话)?
更清楚:标准解释说这是不允许的,我对这个错误的技术原因没有任何疑问:我只是想知道为什么委员会决定使用特殊的额外规则而不是仅仅创建另一个嵌套范围看到开口支撑(就像在其他地方发生的那样).
例如,为了使代码合法,你可以用两个支撑对包裹身体而不是一个...
还请注意for/while/if
,虽然被认为是良好实践,但后面的括号不是强制性的,也不是语法的一部分,但仍然存在包含循环变量的范围(因此使用函数定义作为另一个示例,其中本地的范围是函数不相关:函数体不是语句,括号是强制性的).
在C++语法中,a的主体for
只是一个声明; 但是如果这个语句碰巧是一个支撑组,那么它会得到一个特殊的处理for/while/if
(当你使用支撑组作为语言中的其他语句时不会发生这种情况).
将这种额外的复杂性添加到语言中的原因是什么?它显然不是必需的,只是将括号视为另一个内部范围似乎(对我而言)更简单.
是否存在这种更简单,更常规的方法不起作用的用例?
请注意,我不是在征求意见.要么你知道为什么委员会做出了这个决定(在标准中也需要一个非常精细的措辞,而不是仅仅将正文作为常规处理括号封闭块作为陈述),或者你不这样做.
语法的"单一范围"视图对我来说是不自然的,但在技术上可以用于for
可以合理化为具有反向goto
语句的单个块的语句,但是在if
语句的非常类似的情况下很难防御:
if (int x = whatever()) {
int x = 3; // Illegal
} else {
int x = 4; // Illegal here too
}
Run Code Online (Sandbox Code Playgroud)
但这是合法的
if (int x …
Run Code Online (Sandbox Code Playgroud) 在C++中,标准库包含在std
命名空间中,程序员不应该在该命名空间内定义任何内容.当然,标准包含文件不会在标准库中相互依赖名称(因此包含标准头文件从来都不是问题).
那么为什么不是默认包含整个标准库而不是强迫程序员#include <vector>
每次都编写?这也可以加快编译速度,因为编译器可以从所有标准头文件的预构建符号表开始.
预先包含所有内容也可以解决一些可移植性问题:例如,当你包含<map>
它时,定义了什么符号被带入std
命名空间,但是不保证其他标准符号没有被加载到它中,例如,你可能最终(理论上)与std::vector
也变得可用.
有时会发生程序员忘记包含标准头文件但程序仍会编译,因为包含了特定实现的依赖性.将程序移动到另一个环境(或只是同一编译器的另一个版本)时,相同的源代码可能会停止编译.
从技术角度来看,我可以对编译器进行映像,只需预加载(带mmap
)标准库的最佳完美哈希符号表.这应该比加载和执行甚至单个标准包含文件的C++解析更快,并且应该能够更快地查找std::
名称.该数据也是只读的(因此可能允许更紧凑的表示并且还可以在编译器的多个实例之间共享).
然而,这些应该是我从未实现过的.
我看到的唯一缺点是我们的C++程序员会丢失编译咖啡休息和Stack Overflow访问:-)
为了澄清我看到的主要优点,对于今天的程序员来说,尽管C++标准库是一个单一的命名空间,但需要知道哪个子部分(包含文件)包含哪个函数/类.如果他们犯了错误并且忘记了包含文件,那么代码可能会编译或者根据实现(因此导致非可移植程序)编译或不编译.
在下面的代码中
#include <map>
#include <string>
struct P2d {
double x, y;
P2d(double x, double y) : x(x), y(y) {}
};
double bar() {
std::map<std::string, int> m;
//P2d lp = P2d(double(m["x"]), double(m["y"])); // this works
P2d lp(double(m["x"]), double(m["y"]));
return lp.x;
}
Run Code Online (Sandbox Code Playgroud)
我测试的所有编译器都同意代码(未注释版本)无效,但我不明白为什么定义
P2d lp(<double>, <double>);
Run Code Online (Sandbox Code Playgroud)
我使用的是不可接受的。
我记得规则是“如果它既可以是函数声明又可以是定义,那么它就是声明”,但我希望如果它不能是声明,那么它应该被解释为定义而不是给出错误。
我错过了什么?
我在Opera 11.50上发现了表达式
JSON.stringify(2)
Run Code Online (Sandbox Code Playgroud)
返回一个对象
typeof
回报 "string"
constructor.name
是 String
charCodeAt(0)
是50length
是1但仍然
alert(JSON.stringify(2) == "2")
Run Code Online (Sandbox Code Playgroud)
在Opera中显示"false"(使用时也是如此===
).
这是一个错误还是什么?
我发现让它比较等于"2"的唯一方法是调用.substr(0)
(例如,即使添加一个空字符串仍然比较不同).
用代码就好
#include <iostream>
struct P {
int x;
P(int x) : x(x) {}
~P() { std::cout << "~P()\n"; }
};
int main() {
auto const& x = P{10}.x;
std::cout << "extract\n";
}
Run Code Online (Sandbox Code Playgroud)
GCC打印~P() extract
,表示临时的生命周期未被引用扩展.
相比之下,Clang(IMO正确)将临时的生命周期延长到引用的生命周期,x
因此析构函数将在输出后调用main
.
请注意,如果我们int
使用某种类型(例如string
),GCC会突然显示Clang的行为.
这是GCC中的错误还是标准允许的内容?
在Python 2和Python 3中代码:
class Foo(object):
pass
f = Foo()
f.__call__ = lambda *args : args
f(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)
返回错误Foo object is not callable
.为什么会这样?
PS:对于旧式的类,它按预期工作.
PPS:此行为是有意的(请参阅接受的答案).作为一种解决方法,可以定义一个__call__
类级别,它只是转发给另一个成员,并将这个"普通"成员设置为每个实例的__call__
实现.
在我正在工作的代码库中,我们使用std::any
而不是void*
通过一些通用的非模板代码来传递类。具体来说,我们使用 Visual Studio 2019、它的编译器和标准库。
为了可视化std::any
,微软已经给出了一个natvis:
<Type Name="std::any">
<Intrinsic Name="has_value" Expression="_Storage._TypeData != 0"/>
<Intrinsic Name="_Rep" Expression="_Storage._TypeData & _Rep_mask"/>
<Intrinsic Name="type" Expression="(const type_info*)(_Storage._TypeData & ~_Rep_mask)"/>
<Intrinsic Name="_Is_trivial" Expression="has_value() && _Rep() == 0"/>
<Intrinsic Name="_Is_big" Expression="has_value() && _Rep() == 1"/>
<Intrinsic Name="_Is_small" Expression="has_value() && _Rep() == 2"/>
<DisplayString Condition="!has_value()">[empty]</DisplayString>
<DisplayString Condition="_Is_trivial() || _Is_small()">[not empty (Small)]</DisplayString>
<DisplayString Condition="_Is_big()">[not empty (Large)]</DisplayString>
<Expand>
<Synthetic Name="has_value">
<DisplayString>{has_value()}</DisplayString>
</Synthetic>
<Synthetic Name="type" Condition="has_value()">
<DisplayString>{type()}</DisplayString>
</Synthetic>
<Synthetic Name="[representation]" Condition="_Is_trivial()">
<DisplayString>(Small/Trivial Object)</DisplayString>
</Synthetic>
<Synthetic Name="[representation]" …
Run Code Online (Sandbox Code Playgroud) 我最近被咬了(简化)
struct Base {
typedef char T;
};
template<typename T>
struct Foo : Base {
T x[50]; // This is Base::T, not the template parameter
};
Run Code Online (Sandbox Code Playgroud)
换句话说,类成员名称隐藏模板参数(即使来自基类,因此在本地上下文中并不完全明显).
然而,我做了一些实验,发现:
struct Base {
typedef char T;
};
template<typename T, typename B>
struct Foo : B {
T x[50]; // This T is the template parameter,
// even passing Base as B
};
Run Code Online (Sandbox Code Playgroud)
我能想到的唯一出路是给出丑陋的模板参数名称,也意味着在不使用保留名称的情况下安全地编写模板是不可能的(因为模板中使用的类可能会碰撞参数名称...请注意很多C++代码使用uglyfied名称为私人成员).
PS:我没有深入研究这个问题的标准,但g ++和clang ++都同意这个行为,所以我不认为这是一个bug.
PPS:在实际代码中,隐藏的模板参数被命名tid
,并且是整数而不是类型.-Wall
还没有足够的关于隐藏的问题,我在用valgrind进行了几个小时的调试后发现了它.
如果可以通过连接相同字符串的两个副本来获取字符串,则将其称为方形字符串.例如,"abab","aa"是方形字符串,而"aaa","abba"不是.给定一个字符串,该字符串的子序列有多少是方形字符串?可以通过从中删除零个或多个字符并保持剩余字符的相对顺序来获得字符串的子序列.子序列不必是唯一的.
例如,字符串'aaa'将具有3个方形子序列
c++ ×6
algorithm ×1
c++17 ×1
instance ×1
javascript ×1
json ×1
name-hiding ×1
name-lookup ×1
natvis ×1
opera ×1
python ×1
reference ×1
string ×1
templates ×1
temporary ×1