小编ynn*_*ynn的帖子

为什么 std::hash 不能保证是确定性的?

此后,我们使用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)都是确定性的。效率有问题吗?

c++ hash std language-lawyer

28
推荐指数
2
解决办法
1330
查看次数

在 Rust 中,如果 main 函数返回 Err 会发生什么?

根据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 中稳定下来(来源)。

program-entry-point exit-code language-lawyer rust

26
推荐指数
2
解决办法
3739
查看次数

为什么`mt19937`的默认种子是5489?

根据标准mt19937::default_seed,的值为5489u

static constexpr result_type default_seed = 5489u;
Run Code Online (Sandbox Code Playgroud)

这看起来很人为。

这背后有什么(数学或理论)原因吗?

c++ random c++11 mt19937

20
推荐指数
1
解决办法
1281
查看次数

C ++语言标准是否允许空宏?

根据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)

c++ language-lawyer

18
推荐指数
1
解决办法
780
查看次数

在python中为列表定义数值稳定的sigmoid函数的最佳方法

对于标量变量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 上找不到类似的问题。非常感谢您的时间和帮助!

python sigmoid

12
推荐指数
3
解决办法
6079
查看次数

为什么可以从外部通过指针或引用访问静态本地对象?

如您所知,局部静态变量不能在函数外部通过名称访问,而是可以通过指针或对其的引用来访问。因此,以下代码格式正确。

但为什么?我知道这个事实是事实,但没有根据。实际上我想要的是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)

c++ language-lawyer

8
推荐指数
1
解决办法
164
查看次数

为什么`assert`宏即使具有`NDEBUG`仍具有价值?

环境:

$ g++ --version
g++ (Ubuntu 7.4.0-1ubuntu1~18.04) 7.4.0
Run Code Online (Sandbox Code Playgroud)

众所周知,assert可以NDEBUG在包含assert.hcassert)之前通过定义禁用用于调试的类函数宏。但是,/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)

因此,即使使用NDEBUGassert也会扩展到某个值,从而对性能的影响微不足道,但可以肯定地(如果在预处理步骤之后未进行优化)。由于C ++标准允许类似函数的宏具有空值,因此似乎

#ifdef NDEBUG
#define assert(expr)
#endif
Run Code Online (Sandbox Code Playgroud)

将是一个很好的实现。

有什么理由可以选择非空值?

c c++

8
推荐指数
1
解决办法
247
查看次数

为什么此递归lambda函数不安全?

这个问题来自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表达式?

c++

8
推荐指数
1
解决办法
155
查看次数

仅在分配时才出现奇怪的 AttributeError

我正在实现什么是函数内静态变量的 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)

我不明白为什么这段代码不起作用。根据错误消息, …

python decorator

7
推荐指数
1
解决办法
126
查看次数

如何在 Go 1.22 中的 for-range 循环中迭代整数?

Go 1.22 今天发布了。根据发行说明

“For”循环现在的范围可以是整数。例如:

package main

import "fmt"

func main() {
    for i := range 10 {
        fmt.Println(10 - i)
    }
    fmt.Println("go1.22 has lift-off!")
}
Run Code Online (Sandbox Code Playgroud)

详细信息请参阅规格。

我想了解详细信息,但似乎规范根本没有解释语法。

我添加了#language-lawyer标签,因为我想要严格的理解。

go language-lawyer

7
推荐指数
1
解决办法
596
查看次数