当前位置: 首页 > 知识库问答 >
问题:

什么是平凡函数?

龙珂
2023-03-14

[basic.def.odr]/3引用了术语“非平凡函数”,我在标准(N4140)中找不到它的定义。

[basic.def.odr]/3

除非将左值-右值转换(4.1)应用于x会产生一个不调用任何重要函数的常量表达式(5.19),并且如果x是一个对象,ex是表达式e的一组潜在结果的元素,其中左值-右值转换(4.1)应用于e,或者e是一个丢弃的值表达式(第5条)。

共有2个答案

皇甫繁
2023-03-14

这个小例子可能会帮助您理解[basic.def.odr]/3上下文中的非平凡函数

struct C { 
        int l; 
        constexpr C(int _l) : l(_l) { } 
        constexpr C(const C&c) : q(c.l* 2) { } 
      }; 

      int main(void) { 
        constexpr C c(42); 
        constexpr int m= c.l; 
        struct K{ 
         int foo() { return c.l; } 
        } l; 
        return l.foo(); 
      } 

如果你看一下标准中的以下几行

将左值到右值的转换(4.1)应用于x,得到一个不调用任何非平凡函数的常量表达式(5.19)

在这里,c满足出现在常量表达式中的要求,但将左值到右值的转换应用于a会调用一个非平凡的函数。

为什么它调用一个非平凡的函数?

当未赋值的操作数或其子表达式中发生左值到右值的转换时,不访问被引用对象中包含的值。否则,如果glvalue具有类类型,则转换副本将从glvalue初始化类型为T的临时值,并且转换的结果是临时值的prvalue

因此,prvalue是使用C类的复制构造函数创建的,因为复制构造函数是用户声明的,所以它不是平凡的,因此这里不使用ODR

类X的复制/移动赋值操作符是微不足道的,如果它不是用户提供的,它的参数类型列表等价于隐式声明的参数类型列表

我希望这个例子能澄清你的疑问

尉迟清野
2023-03-14

“非平凡函数”是“平凡特殊成员函数”的补充。对于什么是普通和非普通的默认/复制/移动构造函数、复制/移动赋值运算符或析构函数,有一些定义——这些特性只与特殊成员函数有关,并决定在某些情况下是否需要调用它们。

这些定义见第12章。

默认构造函数,§12.1/4:

如果默认构造函数不是用户提供的,并且:

  • 它的类没有虚拟函数(10.3)和虚拟基类(10.1),并且

否则,默认构造函数是非常重要的。

复制/移动构造函数,§12.8/12:

如果类X的复制/移动构造函数不是用户提供的,它的参数类型列表相当于隐式声明的参数类型列表,并且如果

  • X没有虚拟函数(10.3)和虚拟基类(10.1),并且

否则,复制/移动构造函数就非常重要。

复制/移动分配操作员,§12.8/26:

如果类X的复制/移动赋值运算符不是用户提供的,那么它的参数类型列表相当于隐式声明的参数类型列表,如果

  • X没有虚拟函数(10.3)和虚拟基类(10.1),并且
  • X没有volatile限定类型的非静态数据成员,并且
  • 选择复制/移动每个直接基类的赋值运算符
  • 对于类类型(或其数组)的X的每个非静态数据成员,选择用于复制/移动该成员的赋值运算符是微不足道的

否则,复制/移动赋值运算符就非常重要。

析构函数,§12.4/5:

如果析构函数不是用户提供的,并且如果:

  • 析构函数不是虚拟的,

否则,析构函数就非常重要

 类似资料:
  • 经过稍加搜索,我找到了一个StackOverflow的答案,它用comonoids必须满足的定律更好地解释了这一点。所以我想我明白了为什么在Haskell中只有一个假设的Comonoid类型的可能实例。 因此,要找到一个非平凡的comonoide,我想我们必须从其他类别中寻找。当然,如果范畴理论家有一个comonoids的名字,那么有一些有趣的。该页上的其他答案似乎暗示了一个涉及的示例,但我找不出

  • 本文向大家介绍什么是虚函数?什么是抽象函数?相关面试题,主要包含被问及什么是虚函数?什么是抽象函数?时的应答技巧和注意事项,需要的朋友参考一下 答: 虚函数:没有实现的,可由子类继承并重写的函数。Virtual CallSomeOne(); 抽象函数:规定其非虚子类必须实现的函数,必须被重写。public abstract void CallSomeOne();  

  • 主要内容:C语言中的函数和数学中的函数,库函数和自定义函数,参数,返回值从表面上看,函数在使用时必须带上括号,有必要的话还要传递参数,函数的执行结果也可以赋值给其它变量。例如,strcmp() 是一个用来比较字符串大小的函数,它的用法如下: str1 和 str2 是传递给 strcmp() 的参数,strcmp() 的处理结果赋值给了变量 result。 我们不妨设想一下,如果没有 strcmp() 函数,要想比较两个字符串的大小该怎么写呢?请看下面的代码: 比较字

  • 问题内容: 对于没有计算机科学背景的人来说,计算机科学世界中的lambda是什么? 问题答案: Lambda来自Lambda微积分,是指编程中的匿名函数。 为什么这很酷?它允许您编写快速抛出的函数而无需命名它们。它还提供了写闭包的好方法。有了这种能力,您就可以做这样的事情。 Python 从Python片段中可以看到,函数加法器接受一个参数x,并返回一个匿名函数(即lambda),该函数接受另一个

  • 问题内容: 在JavaScript中,嵌套函数非常有用:闭包,私有方法以及您拥有的东西。 什么是嵌套PHP函数?有人使用它们吗? 这是我做的小调查 问题答案: 基本上没有,我一直将其视为解析器的副作用。 伊兰·加珀林(Eran Galperin)误认为这些功能是某种私有的,只是在运行之前才声明它们。它们也不是私有范围的,尽管确实延迟了,但它们确实污染了全球范围。作为回调,外部回调仍然只能被调用一次

  • 问题内容: Java中有XOR函数- 举个例子: 你能告诉我反函数吗?如果有,我能否获得包括数字在内的数字范围? 问题答案: 反之为XOR! 如果你有: 如果您有其他可用值,则可以获取或返回: 例如,如果,(如前所述),您将得到: