标签: constexpr

我应该像这样使用constexpr吗?

我有这个非常简单的函数,我有一些值需要计算,但只需要一次,最好的时间是在编译时.这些值仅在此函数中有效.这是constexpr的好用还是我应该只声明它们是静态const?

ps我知道性能差异是无关紧要的,但我想用"正确"的c ++ 11方式做到这一点.

void MainWindow::UpdateDateTimes()
{
// for some dumb reason DateTime only has add seconds method
    // so we have to calculate the seconds per hour and the number of hours
    // we do this with static constant values so that the calculations
    // only happen once.
    static constexpr const int secsPerHour = 60 * 60;
    static constexpr const int cdtOffsetHours = -5;
    static constexpr const int edtOffsetHours = -4;
    static constexpr const int cetOffsetHours = 2;
    static …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++11

5
推荐指数
1
解决办法
557
查看次数

为什么要声明一个constexpr

在观看isocpp.org上链接C++ 11教程视频时,我注意到了一些事情:

constexpr int windowWidth{800}, windowHeight{600};
Run Code Online (Sandbox Code Playgroud)

声明这些int变量有什么意义constexpr,而不仅仅是const

constexpr c++11

5
推荐指数
2
解决办法
484
查看次数

使非constexpr积分值适应非类型模板参数,并使代码膨胀

考虑F一个constexpr size_t参数的函数对象I

struct F
{
    template <size_t I>
    constexpr size_t operator()(size <I>) const { return I; }
};
Run Code Online (Sandbox Code Playgroud)

包裹在一个类型中size <I>,其中(为简洁起见)

template <size_t N>
using size = std::integral_constant <size_t, N>;
Run Code Online (Sandbox Code Playgroud)

当然,我们可以I直接传递,但我想通过使用它作为模板参数强调它是constexpr.函数F在这里是虚拟的,但实际上它可以做各种有用的东西,比如从I元组的元素中检索信息.F假定具有相同的返回类型,无论如何I.I可以是任何整数类型,但假设是非负的.

问题

给定一个constexpr size_tI,我们可以调用F

F()(size <I>());
Run Code Online (Sandbox Code Playgroud)

现在,如果我们想F用非constepr size_t值调用i怎么办?考虑以下:

constexpr size_t L = 10;
idx <F, L> f;
for (size_t i = …
Run Code Online (Sandbox Code Playgroud)

c++ inlining template-function constexpr c++11

5
推荐指数
1
解决办法
451
查看次数

无法创建静态constexpr

我有以下代码:

struct Literal
{
    int val;
    constexpr Literal(int const& val) : val(val) {}
    constexpr Literal(Literal const& rhs) : val(rhs.val) {}
};


struct Parent
{
    struct StaticObject
    {
        Literal const zero;

        constexpr StaticObject() :zero(0) {}
    };
    static constexpr StaticObject outer{};
};
Run Code Online (Sandbox Code Playgroud)

行'static constexpr StaticObject outer {};' 给我错误:

'表达式没有评估为常数'

接下来是

注意:失败是由调用未定义的函数或未声明'constexpr'的函数引起的

注意:请参阅'Parent :: StaticObject :: StaticObject'的用法

据我所知,这里使用的所有函数都是定义和声明的constexpr.我错过了什么,或者这是一个编译器错误?

c++ constexpr c++11

5
推荐指数
0
解决办法
95
查看次数

使用constexpr函数在g ++中的不同行为 - 7.0 /访问硬件

我使用以下代码访问某些MCU寄存器.

#include <stdint.h>

struct MCU {
    struct Timer {
        volatile uint8_t r1;
        template<int N> struct Address;
    };
};
template<>
struct MCU::Timer::Address<0> {
    static constexpr uint8_t value = 0x25;
};

template<typename Component, int Number>
constexpr Component* getBaseAddr() {
    return reinterpret_cast<Component*>(Component::template Address<Number>::value);
}

struct Test {
    static void foo() {
        p->r1 = 42;    
    }
    static constexpr auto p = getBaseAddr<MCU::Timer, 0>();
};

int main() {
    Test::foo();

    while(true) {}
}
Run Code Online (Sandbox Code Playgroud)

在avr-g ++ 6.2.1中,这很好用.但现在使用avr-g ++ 7.0我得到错误:

in constexpr expansion of 'getBaseAddr<MCU::Timer, 0>()'
bm10a.cc:23:58: error: …
Run Code Online (Sandbox Code Playgroud)

c++ reinterpret-cast constexpr

5
推荐指数
1
解决办法
93
查看次数

C ++ 11中ConstExpr对象中的可变成员

在C ++ 14标准(ISO / IEC 14882:2014)中,第5.19节第2款(强调我的)中添加了“ 不可更改 ”一词:

条件表达式 e是一个核心常量表达式除非e的评价,如下所述抽象机(1.9),将评估下面的表达式中的一个的规则:

  • [...]
  • 左值到右值转换(4.1),除非将其应用于
    • [...]
    • 非易失性glvalue,它引用用constexpr定义的非易失性对象,或引用该对象的不可更改子对象,或者

因此,此代码在C ++ 14中不正确:

class A {
    public:
        mutable int x;
};

int main(){

    constexpr A a = {1};
    constexpr int y = a.x;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是,在C ++ 11中是否正确?

这是缺陷报告(CD3)1405,他们提议在其中添加非可变的

当前,文字类类型可以具有可变成员。尚不清楚这是否会对constexpr对象和常量表达式造成任何特殊的问题,如果是这样,应该如何处理。

所以我会说这是正确的C ++ 11代码。尽管如此,我还是使用-std = c ++ 11尝试了Clang和GCC,并且都输出了一个错误,指出常量表达式中不允许使用可变变量。但是该约束是在C ++ 14中添加的,而在C ++ 11中则没有。

有谁知道该代码在C ++ 11中是否正确?

另请参阅缺陷报告(CD3)1428

c++ mutable constexpr c++11 c++14

5
推荐指数
1
解决办法
328
查看次数

用于连接constexpr std :: array的体系结构x86_64的未定义符号

我在链接我的目标文件时收到错误:

#include <cstdint>
#include <array>

enum SystemType : uint8_t { AC, DC, HCP, EFF };

template<SystemType TYPE> struct System;

template<> 
struct System<AC> { 
public:     
static constexpr size_t number_of_sockets = 2;  
static constexpr std::array<size_t, number_of_sockets> object_per_socket { { 12, 6 } }; 
};
Run Code Online (Sandbox Code Playgroud)

我正在使用它如下所示将数据分配到向量中.

terminal->no_obj_per_system.assign(
            Sytem<AC>::object_per_socket.begin(),
            Sytem<AC>::object_per_socket.end());
Run Code Online (Sandbox Code Playgroud)

我在mac Os上使用clang.

c++ constexpr c++14

5
推荐指数
1
解决办法
372
查看次数

constexpr函数的主体不是return语句

在下面的程序中,我添加了一个显式return语句func(),但编译器给出了以下错误:

m.cpp: In function ‘constexpr int func(int)’:
m.cpp:11:1: error: body of constexpr function ‘constexpr int func(int)’ not a return-statement
 }
Run Code Online (Sandbox Code Playgroud)

这是代码:

#include <iostream>
using namespace std;

constexpr int func (int x);

constexpr int func (int x) 
{
    if (x<0)                
        x = -x;
    return x; // An explicit return statement 
}

int main() 
{
    int ret = func(10);
    cout<<ret<<endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我使用以下命令在g ++编译器中编译了程序.

g++ -std=c++11 m.cpp
Run Code Online (Sandbox Code Playgroud)

return在函数中添加了语句,然后为什么我出现上述错误?

c++ function return-type constexpr c++11

5
推荐指数
2
解决办法
6481
查看次数

在编译时查找数组中的重复项

我正在尝试学习一些更现代的C++实践,比如模板,我决定创建一个天真简单的命令行参数解析器,它主要在编译时工作,我已经constexpr遇到了问题,基本上我想做的就是检查对于编译时的重复条目(在运行时执行它是微不足道的).

首先,我有一个包含单个配置的结构:

struct Arg_Opt_Tuple {
  std::string_view mc{}; // multichar ie "help" 
  char sc{}; // singlechar ie 'h' 
  bool is_flag{}; 
};
Run Code Online (Sandbox Code Playgroud)

现在让我们说我想创建一个函数(或者最终是对象的构造函数),它返回一个固定大小的std :: array,但是在编译时也会检查重复项或空值,我的目标是让它调用一些与此类似的时尚:

constexpr auto ARG_COUNT = 4U;
constexpr auto opts = checked_arr<ARG_COUNT>(
  Arg_Opt_Tuple{"hello", 'h', false},
  Arg_Opt_Tuple{"world", 'g', true},
  Arg_Opt_Tuple{"goodbye", 'h', false}, // <- static_assert('h' == 'h')
  Arg_Opt_Tuple{"hello", 'r', false} // <- static_assert(sv.compare("hello") == 0)
);
Run Code Online (Sandbox Code Playgroud)

我的第一次尝试是使用std :: initializer_list但遇到了一些问题,在做了一些谷歌搜索结束后得出结论与constexpr一起做的不正确.我目前的尝试涉及一个可变参数模板:

template <std::size_t N, typename... T>
constexpr std::array<Arg_Opt_Tuple, N> checked_arr(T... list) {
  static_assert(N == sizeof...(T));
  return {list...};
}
Run Code Online (Sandbox Code Playgroud)

这可以工作,但对于只是初始化一个数组是完全多余的,我真的希望这是做一些编译时间检查.对于重复或错误的值在运行时很容易,你可以循环并比较或做std :: …

c++ variadic-templates constexpr c++11

5
推荐指数
1
解决办法
215
查看次数

模板内联constexpr变量的地址是否被gcc视为常量表达式?

template <typename T>
inline constexpr int a = 1;

static_assert(&a<void>, "");
Run Code Online (Sandbox Code Playgroud)

不会在gcc 9.2上进行编译,但是会在clang和msvc上进行编译。

Gcc抱怨用于的表达式static_assert不是常量表达式。

The code compiles after removing template, removing inline, or removing address-of operator.

Is this a gcc bug?

c++ gcc compiler-bug constexpr c++17

5
推荐指数
0
解决办法
48
查看次数