此后,我们使用N4140(C++14 标准)。
根据§ 17.6.3.4 哈希要求,
返回值应仅取决于
k程序持续时间的参数。[注意:因此,对于给定的程序执行,
h(k)具有相同值 的表达式的所有评估都会k产生相同的结果。— 尾注 ]
和§ 20.9.12 类模板哈希说
...
实例化
hash<Key>应:(1.1) — 满足哈希要求 (17.6.3.4) ...
(1.2) — ...
这意味着如果您重新启动程序,value(ie hash<decltype(value)>(value))的哈希值可能会采用不同的值。
但为什么?这个限制不在 C++11 的标准中,而是在 C++14、C++17 和 C++20 的标准中。作为用户(不是 STL 开发人员),如果std::hash是确定性的,那将非常有用。在实现确定性散列函数时有什么数学上的困难吗?但是我们日常使用的散列函数(例如已弃用md5sum或更安全sha256)都是确定性的。效率有问题吗?
根据Rust 参考资料,
如果
main存在函数(snip),并且其返回类型必须是以下类型之一:
()
Result<(), E> where E: Error
但它没有说明当main()return()或Ok(())时会发生什么Err(<value>)。
据我测试,
() |
Ok(()) |
Err(<value>) |
|
|---|---|---|---|
| 退出状态 | 0 | 0 | 1 |
| 附加行为 | - | - | Error: <value>被打印到stderr |
这些行为是否在某些文档中定义、明确解释或保证?特别是,我可以假设
返回时程序总是以1状态退出?main()Err(<value>)
main()返回时显示的错误消息Err(<value>)始终是以下形式Error: <value>?
笔记:
我想要某种有据可查的保证,而不是经验性的解释。这就是我添加#language-lawyer标签的原因。
这个问题不是关于什么时候应该使用()以及什么时候应该使用Result<(), E>?或诸如此类。如您所知,人们可以在许多文档或教程中找到此类问题的答案(或至少是提示或标准)。
更新:
TerminationTrait 最终在 Rust 1.61.0 中稳定下来(来源)。
根据标准mt19937::default_seed,的值为5489u:
static constexpr result_type default_seed = 5489u;
Run Code Online (Sandbox Code Playgroud)
这看起来很人为。
这背后有什么(数学或理论)原因吗?
根据N3092(C ++ 11最终委员会草案),在16.3:宏替换中,类对象宏定义为:
#定义标识符 替换列表 换行符
并且类似函数的宏定义为:
#定义标识符 lparen identifier-list_opt)替换列表换 行 #定义标识符 lparen ...)替换列表换 行 #定义标识符 lparen 标识符列表 ... ...)替换列表换 行
全部都有替换列表(所谓的宏值),其定义为:
替换列表:
pp-tokens opt
和PP-令牌被定义为:
pp-tokens:
预处理令牌
pp-tokens 预处理令牌
和预处理令牌是,例如,标识符。
据我所知,带有空值的宏是定义良好的。
但是,16.3-3说:
在类似对象的宏的定义中,标识符和替换列表之间应有空白。
并请注意,替换列表本身不是可选的(尽管它可以具有空值)。
所以我相信:
//well-formed (function-like macro with value)
#define f(x) (x)<NEWLINE>
//well-formed (function-like macro without value)
#define f(x)<NEWLINE>
//well-formed (function-like …Run Code Online (Sandbox Code Playgroud) 对于标量变量x,我们知道如何在python中写出数值稳定的sigmoid函数:
def sigmoid(x):
if x >= 0:
return 1. / ( 1. + np.exp(-x) )
else:
return exp(x) / ( 1. + np.exp(x) )
Run Code Online (Sandbox Code Playgroud)
对于标量列表z = [x_1, x_2, x_3, ...],假设我们x_i事先不知道每个标量的符号,我们可以概括上面的定义并尝试:
def sigmoid(z):
result = []
for x in z:
if x >= 0:
result.append(1. / ( 1. + np.exp(-x) ) )
else:
result.append( exp(x) / ( 1. + np.exp(x) ) )
return result
Run Code Online (Sandbox Code Playgroud)
这似乎有效。但是,我觉得这可能不是最 Pythonic 的方式。我应该如何改进“清洁”方面的定义?说,有没有办法使用理解来缩短函数定义?
如果有人问过这个,我很抱歉,因为我在 SO 上找不到类似的问题。非常感谢您的时间和帮助!
如您所知,局部静态变量不能在函数外部通过名称访问,而是可以通过指针或对其的引用来访问。因此,以下代码格式正确。
但为什么?我知道这个事实是事实,但没有根据。实际上我想要的是C ++标准的相关摘录。我正在阅读,但最终没有找到证据。有人可以给我摘录或提示找我吗(因为仅在文档中搜索“ static”会导致一百多个匹配)?
#include <iostream>
using namespace std;
class Test {
public:
int * f(int i) const {
static int j;
j += i;
cout << "now j = " << j << "\n";
return &j;
}
int & g(int i) const { //same as above but handle reference
static int k;
k += i;
cout << "now k = " << k << "\n";
return k;
}
};
int main() {
Test t;
int *p = …Run Code Online (Sandbox Code Playgroud) 环境:
$ g++ --version
g++ (Ubuntu 7.4.0-1ubuntu1~18.04) 7.4.0
Run Code Online (Sandbox Code Playgroud)
众所周知,assert可以NDEBUG在包含assert.h(cassert)之前通过定义禁用用于调试的类函数宏。但是,/usr/include/assert.h在我的环境中阅读后,我发现了下面的代码。
#if defined __cplusplus && __GNUC_PREREQ (2,95)
# define __ASSERT_VOID_CAST static_cast<void>
#else
# define __ASSERT_VOID_CAST (void)
#endif
#ifdef NDEBUG
# define assert(expr) (__ASSERT_VOID_CAST (0))
# ifdef __USE_GNU
# define assert_perror(errnum) (__ASSERT_VOID_CAST (0))
# endif
#else /* Not NDEBUG. */
Run Code Online (Sandbox Code Playgroud)
因此,即使使用NDEBUG,assert也会扩展到某个值,从而对性能的影响微不足道,但可以肯定地(如果在预处理步骤之后未进行优化)。由于C ++标准允许类似函数的宏具有空值,因此似乎
#ifdef NDEBUG
#define assert(expr)
#endif
Run Code Online (Sandbox Code Playgroud)
将是一个很好的实现。
有什么理由可以选择非空值?
这个问题来自lambda函数可以递归吗?。该接受的答案说,下面的作品显示递归lambda函数。
std::function<int (int)> factorial = [&] (int i)
{
return (i == 1) ? 1 : i * factorial(i - 1);
};
Run Code Online (Sandbox Code Playgroud)
但是,有评论指出
这样的功能不能安全地返回
,并且此注释中提供了原因:
返回它会破坏局部变量,并且该函数具有对该局部变量的引用。
我不明白原因。据我所知,捕获变量等效于将其保留为数据成员(根据捕获列表的按值或按引用)。那么在这种情况下什么是“局部变量”?此外,即使使用7.4.0中的-Wall -Wextra -std=c++11选项,下面的代码也可以编译并正常工作g++。
#include <iostream>
#include <functional>
int main() {
std::function<int (int)> factorial = [&factorial] (int i)
{
return (i == 1) ? 1 : i * factorial(i - 1);
};
std::cout << factorial(5) << "\n";
}
Run Code Online (Sandbox Code Playgroud)
为什么功能不安全?此问题是否仅限于此函数或整个lambda表达式?
我正在实现什么是函数内静态变量的 Python 等效项中描述的装饰器?. 在答案中,装饰器被置于一个正常的功能上,它也在我的环境中工作。
现在我想把装饰器放到一个类方法上。
源代码:
#decorator
def static_variabls(**kwargs):
def new_func(old_func):
for key in kwargs:
setattr(old_func, key, kwargs[key])
return old_func
return new_func
class C:
@static_variabls(counter = 1)
def f_(self) -> None:
print(self.f_.counter)
self.f_.counter += 1
c1 = C()
c1.f_()
c1.f_()
c1.f_()
Run Code Online (Sandbox Code Playgroud)
预期结果:
1
2
3
Run Code Online (Sandbox Code Playgroud)
实际结果:
1
Traceback (most recent call last):
File "1.py", line 16, in <module>
c1.f_()
File "1.py", line 13, in f_
self.f_.counter += 1
AttributeError: 'method' object has no attribute 'counter'
Run Code Online (Sandbox Code Playgroud)
我不明白为什么这段代码不起作用。根据错误消息, …
Go 1.22 今天发布了。根据发行说明,
“For”循环现在的范围可以是整数。例如:
Run Code Online (Sandbox Code Playgroud)package main import "fmt" func main() { for i := range 10 { fmt.Println(10 - i) } fmt.Println("go1.22 has lift-off!") }详细信息请参阅规格。
我想了解详细信息,但似乎规范根本没有解释语法。
我添加了#language-lawyer标签,因为我想要严格的理解。