首页
学习
活动
专区
圈层
工具
发布

性能优化利器之constexpr

今天,聊聊在升级过程中的一个比较重要的优化点-编译期优化。 概述 说明符constexpr是自C++11引入,我相信很多人跟我一样,在第一次接触这个的时候,会很容易和const混淆。...前面提到了constexpr是在编译阶段进行求值,那么也就是说在程序运行之前,就已经计算完成,这种无疑大大提升了程序的运行效率。...} } 这样就能很清楚的知道为什么编译失败了,因为在代码中存在t.value * t.value操作,而对于一个int来说并没有value这个变量,所以编译失败。...,如果是算术类型,则调用第一个,否则调用第二个,完整代码如下: #include templateT> typename std::enable_if函数借助std::enable_if来实现,代码上多少有点冗余,在这个时候,本节的主角if constexpr 出场,完整代码如下: #include

78910

​数组和C++ std::array详解

,否则编译失败 2.1.2 元素访问 at at用于访问指定的元素,同时进行越界检查,该函数返回位于指定位置pos的元素的引用,如果pos不在容器的范围内,则抛出std::out_of_range异常...同时函数中T 必须符合可相等比较 (EqualityComparable) 的要求 3-6中按照字典比较lhs和rhs的内容,其内部等价于调用std::lexicographical_compare函数进行比较...其内部等价于调用std::lexicographical_compare_three_way 进行比较。返回类型同合成三路比较的结果类型。其逻辑大致如下: lhs (arr) << ")\n"; //输出结果为 (1, 2, 3) std::swap(std::array) std::swap(std::array)函数是为std::array特化std:...打印结果为4 1 5 2 std::to_array std::to_array函数声明如下: templateT, std::size_t N> constexpr std::array

1.5K10
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    C++23中std::optional和std::expected的单子式操作

    一种常见的使用情况是作为一个可能失败的函数的返回值。...2.2 std::expectedstd::expectedT, E>是C++23标准库中的新成员,旨在提供一种类型安全的方式来表示可能成功或失败的操作结果。...三、std::optional的单子式操作3.1 transformtransform函数用于对std::optional中的值应用一个函数,并返回一个新的std::optional,其中包含应用函数后的结果...四、std::expected的单子式操作4.1 transformtransform函数用于对std::expected中的值应用一个函数,并返回一个新的std::expected,其中包含应用函数后的结果...如果std::expected包含值,则返回该值;如果包含错误,则调用提供的函数并返回其结果。

    45000

    Chapter 3: Moving to Modern C++

    ::initializer_lists和构造函数重载解析的同时出现时容易造成错误调用 在调用构造函数的时候,只要不涉及到std::initializer_list参数,括号和花括号初始化有相同的含义...construction 编译器非常偏向选择std::initializer_list构造函数,以至于即便最匹配的std::initializer_list构造函数不能被调用,编译器也会优先选择它...std::initializer_list构造函数时,此时调用空的花括号初始化,编译器会解析为调用默认构造函数,而要解析成std::initializer_list构造函数,需要在花括号中嵌套一个空的花括号进行初始化...,否则会编译失败,这在C++98中会推迟到链接阶段才会报错 删除的函数是pulic而不是private,因为当客户端代码试图使用这个删除的成员函数时,C++会首先检查访问权限,后检查删除状态,如果设为...字面值类型包括除了void修饰的类型和带有constexpr修饰的用户自定义类型(因为构造函数和其他成员函数也可能是constexpr) class Point { public:

    2.1K60

    C++23 中 constexpr 的重要改动

    1. constexpr 函数中使用非字面量变量、标号和 goto (P2242R3)在 C++23 之前,constexpr 函数的使用受到较多限制,不能在其中使用非字面量变量、标号和 goto 语句...nonliteral 是一个非字面类型而导致编译失败,尽管导致失败的那一行代码并不在常量求值的上下文中。...如果我们想在 constexpr 函数中调用一段保证在编译时求值的代码,需要将这段代码放在 if consteval 或 if (std::is_constant_evaluated()) 条件下的代码块中...不存在满足核心常量表达式要求的调用的 constexpr 函数 (P2448R2)在 C++23 中,对于那些不存在满足核心常量表达式要求的调用的 constexpr 函数,也有了新的处理方式。...函数的返回类型和形参类型不必为字面类型P2448R2使 constexpr 函数的使用更加灵活,可处理更多类型的数据不存在满足核心常量表达式要求的调用的 constexpr 函数P2448R2对于不满足核心常量表达式要求的调用的

    28310

    C++20新特性个人总结

    T>::value; // 对模板类型T添加std::is_arithmeticT>::value为true的约束,并对具有约束的新的类型声明number // 使用具有约束的类型,调用该函数时,T...{     std::is_classT>::value; // T是一个类型     t(); // T类型有重载括号运算符,且是无参的     t.run(); // T类型具有run()成员函数...2.9  ADL与不可见的模板函数  ADL是C++本来就有的机制,用于自动推断调用的函数的位置,从而简化代码的编写。而新特性扩展了ADL机制,可以用于模板函数的推断。 ...; // 输出true     return 0; }  ②模板参数的成员函数调用  因为模板参数是处于编译期计算的,因此,作为调用用于自定义类型的模板参数的成员函数时,这些成员必须是constexpr...,则类的对象必须通过其中一个构造函数进行初始化。

    2.4K50

    Modern c++快速浅析

    因为这是一个拷贝指针的操作,因此保留原指针的不可更改指向性并没有太大的意义 auto 大多数情况下auto推断出来的结果和模板类型推导的结果是一样的,不同点在于对大括号初始物的处理 值与指针等推导 const...,但是它们调用的函数可能会抛出异常。...,它的结果就是constexpr的,否则它的运作方式和普通函数无异(编译器不对constexpr做处理) constexpr int pow(int base, int exp) noexcept {...也正因为此当调用Lambda时对该数据的访问是该数据当前的数值 Constexpr Lambda 此功能需要开启_std:c++17_ 显式constexpr auto lambda = [](int...::endl; }; } }; 捕获的是*this时,捕获的类型是const T,即匿名函数体中只能调用到常函数,如果想调用其他成员函数,需要加mutable修饰(修改变量同理,需要使用mutable

    97410

    C++那些事之SFINAE

    根据名称找出所有适用的函数和函数模板对于适用的函数模板,要根据实际情况对模板形参进行替换; 替换过程中如果发生错误,这个模板会被丢弃 在上面两步生成的可行函数集合中,编译器会寻找一个最佳匹配,产生对该函数的调用...一个简单的函数调用,如“f(obj);”在c++中,激活一个机制,根据参数obj来确定应该调用哪个f函数。...您可能还想知道为什么它不能与继承一起使用。C ++中的继承和动态多态性是一个在运行时可用的概念,换句话说,就是编译器将不会拥有且无法猜测的数据!...0的分支,说明obj没有serialize函数,但是却调用了,当然出错了。...不用担心,我们将在c++ 14中使用其中的一些。 5.C++14的优势 5.2 auto与lambda 根据我的XFCE环境右上角的公历,我们是2015年!

    2.9K20

    C++20 Text Formattingfmtlib 适配问题小记

    其中 Text Formatting 是一个我个人比较感兴趣的新组件。它主要是解决了之前字符串格式化库 ( printf 系 ) 的效率问题和运行时安全的问题。 并且新的格式设置的形式也比较友好。...它的含义是可在编译期求值(注意和 const 关键字区分开来,一个函数和类型申明可以是 consteval 但不是 const 的)。...的调用其实就不再是编译期可以求值的 constexpr 了(因为上层的函数签名没有这个保证)。...) { // 我们会在这里处理额外的调用者信息处理和使用自己的缓冲区 // 然后调用 std::format_to_n(...)...是没问题的,仅仅是 fmt::format_to_n(...) 会报错,为什么呢?我们可以先来回顾一下 fmt::format(...) 的声明: template <typename...

    1.7K20

    浅谈 C++ 元编程

    isBadT> 是否为 true。这会导致:两次绑定中,有一次会失败。...一般思路是:提供两类重载 —— 一类接受 任意参数,内部 递归 调用自己;另一类是前者的 模板特化 或 函数重载,直接返回结果,相当于 递归终止条件。它们的重载条件可以是 表达式 或 类型。...函数 _Factor 有两个重载:一个是对任意非负整数的,一个是对 0 为参数的。前者利用递归产生结果,后者直接返回结果。...函数 Sum 有两个重载:一个是对没有函数参数的情况,一个是对函数参数个数至少为 1 的情况。和定长模板的迭代类似,这里也是通过 递归 调用实现参数遍历。...Sum 函数模板,其中一个展开参数包进行递归调用)。

    3.9K61

    C++反射深入浅出 - 1. ponder 反射实现分析总篇

    = nullptr); Real x = fieldX->get(obj).to(); 对于函数的调用 , 我们使用的代码: const reflection::Function*...另外一点是meta function没有像C#那样直接给出Invoke方法, 这个是因为目前的实现针对不同使用场合, 类型擦除的函数是不同的, 比如对于lua, 类型擦除的函数原型是 lua_CFunction...的特化实现各类, 详见下文 Details: 函数的具体信息, 如返回值类型, 参数表tuple等, 都存储在其中 BoundType: 函数类型 ExposedType: 返回值类型...UserObject(T* object); 对类型T的构造实现, 注意内部调用的是前面介绍的makeCopy()静态方法, 所以通过这种方式构造的UserObject是生命周期安全的. 5.1.3...7.2 函数调用 template <typename...

    1.5K20
    领券