gpt4 book ai didi

c++ - 我应该像这样使用 constexpr 吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:20:46 24 4
gpt4 key购买 nike

我有这个非常简单的函数,我有一些值需要计算,但只计算一次,最好的时间是在编译时。这些值只在这个函数中很重要。这是对 constexpr 的良好使用还是我应该将它们声明为静态常量?

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 constexpr const int cdtOffsetSecs = secsPerHour * cdtOffsetHours;
static constexpr const int edtOffsetSecs = secsPerHour * edtOffsetHours;
static constexpr const int cetOffsetSecs = secsPerHour * cetOffsetHours;

QDateTime time( QDateTime::currentDateTimeUtc() );

ui->mTimeLocal->setDateTime( time.toLocalTime() );

ui->mTimeCDT->setDateTime( time.addSecs( cdtOffsetSecs ) );
ui->mTimeEDT->setDateTime( time.addSecs( edtOffsetSecs ) );
ui->mTimeCET->setDateTime( time.addSecs( cetOffsetSecs ) );
}

最佳答案

你的使用很好,如果不是有点冗长的话。在此上下文中,constexprconst 的意思完全相同。任一个(甚至两个)都可以。

Fwiw,std::chrono::hours::period::num 将是指定 60*60 的另一种方式(如果你想炫耀一些 C++11 信誉 :-)).

或者实际上你可以这样做:

void MainWindow::UpdateDateTimes()
{
constexpr std::chrono::seconds cdtOffsetSecs = std::chrono::hours(-5);
constexpr std::chrono::seconds edtOffsetSecs = std::chrono::hours(-4);
constexpr std::chrono::seconds cetOffsetSecs = std::chrono::hours(2);

QDateTime time( QDateTime::currentDateTimeUtc() );

ui->mTimeLocal->setDateTime( time.toLocalTime() );

ui->mTimeCDT->setDateTime( time.addSecs( cdtOffsetSecs.count() ) );
ui->mTimeEDT->setDateTime( time.addSecs( edtOffsetSecs.count() ) );
ui->mTimeCET->setDateTime( time.addSecs( cetOffsetSecs.count() ) );
}

我也想放弃 static。在我的系统上,使用或不使用 static 都会生成完全相同的代码。这一切都在编译时发生,因此不需要 static“仅一次”初始化语义。

更新

为了使这一点变得清晰,我将原始示例编辑为:

void f(int);

void UpdateDateTimes()
{
constexpr std::chrono::seconds cdtOffsetSecs = std::chrono::hours(-5);
constexpr std::chrono::seconds edtOffsetSecs = std::chrono::hours(-4);
constexpr std::chrono::seconds cetOffsetSecs = std::chrono::hours(2);

f(cdtOffsetSecs.count());
}

使用 clang++ 和 libc++ 使用 -O1(几乎没有启用优化)编译它,程序集是:

    .globl  __Z15UpdateDateTimesv
.align 4, 0x90
__Z15UpdateDateTimesv: ## @_Z15UpdateDateTimesv
.cfi_startproc
## BB#0:
pushq %rbp
Ltmp2:
.cfi_def_cfa_offset 16
Ltmp3:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp4:
.cfi_def_cfa_register %rbp
movl $-18000, %edi ## imm = 0xFFFFFFFFFFFFB9B0
popq %rbp
jmp __Z1fi ## TAILCALL
.cfi_endproc

然后我用相同的设置编译了这个程序:

void UpdateDateTimes2()
{
f(-18000);
}

生成的程序集是:

    .globl  __Z16UpdateDateTimes2v
.align 4, 0x90
__Z16UpdateDateTimes2v: ## @_Z16UpdateDateTimes2v
.cfi_startproc
## BB#0:
pushq %rbp
Ltmp7:
.cfi_def_cfa_offset 16
Ltmp8:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp9:
.cfi_def_cfa_register %rbp
movl $-18000, %edi ## imm = 0xFFFFFFFFFFFFB9B0
popq %rbp
jmp __Z1fi ## TAILCALL
.cfi_endproc

所以恕我直言,这几乎是人们最接近 free lunch 的时候了。 . :-)

关于c++ - 我应该像这样使用 constexpr 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15913309/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com