C++ 是否定义为向C+;提供空范围+;标准算法?

C++ 是否定义为向C+;提供空范围+;标准算法?,c++,c++11,language-lawyer,std,C++,C++11,Language Lawyer,Std,接着,我们可以证明标准允许我们将空范围传递给标准算法吗? 第24.1/7段将“空范围”定义为范围[i,i)(其中i有效),并且i似乎可以从自身“到达”,但我不确定这是否符合证明条件 特别是,我们在查看排序函数时遇到了麻烦。例如,std::sort: 复杂性:O(N log(N))(其中N==最后一次-第一次)比较 由于log(0)通常被认为是未定义的,并且我不知道0*未定义的是什么,这里会有问题吗 (是的,好吧,我有点迂腐。当然,如果将空范围传递给std::sort,任何自尊心强的stdlib

接着,我们可以证明标准允许我们将空范围传递给标准算法吗?

第24.1/7段将“空范围”定义为范围
[i,i)
(其中
i
有效),并且
i
似乎可以从自身“到达”,但我不确定这是否符合证明条件

特别是,我们在查看排序函数时遇到了麻烦。例如,
std::sort

复杂性:
O(N log(N))
(其中
N
==
最后一次
-
第一次
)比较

由于
log(0)
通常被认为是未定义的,并且我不知道
0*未定义的是什么,这里会有问题吗



(是的,好吧,我有点迂腐。当然,如果将空范围传递给
std::sort
,任何自尊心强的stdlib实现都不会导致实际问题。但我想知道这里的标准措辞是否存在潜在漏洞。)

大O符号是根据函数的极限定义的。实际运行时间
g(N)
的算法是
O(f(N))
当且仅当
lim N→∞ g(N)/f(N)
是一个非负实数
g(N)/f(N)
对于所有值
N
大于某个常数
k
C
k
的精确值无关紧要;您只需找到任何
C
k
即可实现此目的)。(感谢您的更正,杰西!)


您会注意到,元素的实际数量在big-O分析中并不相关。big-O分析对少量元素的算法行为没有任何说明;因此,
f(N)并不重要
是在
N=0
定义的。更重要的是,实际的运行时行为是由不同的函数
g(N)
控制的,即使
f(0)
没有定义,也可以在
N=0
定义。

除了@bdonlan给出的相关答案之外,还要注意
f(N)=N*log(N)
确实有一个定义明确的极限,即
n
变为零,即
0
。这是因为对数的发散速度比任何多项式都慢,特别是比
n
慢。所以一切都很好:-)

我似乎没有太多的疑问。在§24.1/6中,我们被告知:

当且仅当存在使i==j的表达式++i的有限应用程序序列时,迭代器j才被称为可从迭代器i访问

以24.1/7美元计算:

范围[i,j]在且仅当j可从i到达时有效

由于
0
是有限的,
[i,i)
是一个有效范围。§24.1/7接着说:

将库中的函数应用于无效范围的结果为 未定义


这还不至于说一个有效的范围可以保证定义的结果(合理,因为还有其他要求,比如比较函数)但这显然意味着一个范围为空,其本身不应导致UB或类似的结果。然而,特别是,该标准使一个空范围成为另一个有效范围;空有效范围和非空有效范围之间没有真正的区别,因此适用于非空有效范围的内容同样适用于空valid范围。

好的,所以复杂性要求没有问题,我们可以依靠范围满足所有声明的迭代器要求这一事实?我不能对标准的措辞说话,因为我没有标准的副本,对不起。好的;这就是我想要的,真的。学究气(因为OP也是:),Big-O符号与极限无关;
g(N)
是范围
I
上的
O(f(N))
如果存在某个正常数
C
使得
g(N)顺便说一句,我试图得出的主要区别是
g(N)/f(N)
的极限可能不存在(它只需要有一个上限).因此,用户需要阅读
语言律师
标签wiki:«典型问题涉及“实践中通常可行的内容”和“规范实际保证的内容”之间的差距.»的确如此。我认为你的回答与我迄今为止的结论是一致的,而且它似乎是我能想到的最彻底的。但是,例如,
下限
,它的复杂性要求是“最多
log2(最后一个)+O(1)
比较”。对数部分不使用O表示法,因此@bdonlan的参数不适用;
log2(n)
没有限制,因为
n
变为零。我们在这里能做的最好的事情是论证
log2(0)
是负数(即使它没有定义),并且(如果我们谈论的是C++11)调用17.5.1.4/6(“如果复杂度要求的公式要求负操作数,则实际要求为零操作。”)@迈克:好吧,很公平,不过实际上一开始就没有什么问题,因为大O符号描述了渐近行为,所以任何有界区间上的行为都是不相关的。不过,谢谢你指出这一点:-)