C++ 我应该像这样使用constexpr吗?
我有一个非常简单的函数,我有一些需要计算的值,但只有一次,最好的时间是在编译时。这些值仅在该函数中起作用。这是constexpr的一个很好的用途,还是我应该将它们声明为static const ps我知道性能差异是如此之小以至于无关紧要,但我想用“正确”的c++11方法来实现它C++ 我应该像这样使用constexpr吗?,c++,c++11,constexpr,C++,C++11,Constexpr,我有一个非常简单的函数,我有一些需要计算的值,但只有一次,最好的时间是在编译时。这些值仅在该函数中起作用。这是constexpr的一个很好的用途,还是我应该将它们声明为static const ps我知道性能差异是如此之小以至于无关紧要,但我想用“正确”的c++11方法来实现它 void MainWindow::UpdateDateTimes() { // for some dumb reason DateTime only has add seconds method // so we
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 ) );
}
你的使用很好,如果不是有点冗长的话。在此上下文中,
constepr
和const
的意思完全相同。任何一个(甚至两个)都可以
Fwiw,std::chrono::hours::period::num
将是另一种指定60*60
(如果您想展示一些C++11 cred:-)
或者实际上你可以这样做:
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
,都会生成完全相同的代码。这一切都发生在编译时,因此不需要静态
“一次性”初始化语义
更新
为了清楚地说明这一点,我将原始示例编辑为:
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());
}
使用-O1(几乎未启用优化)和clang++和libc++编译,程序集为:
.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
.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
然后我用相同的设置编译了这个程序:
void UpdateDateTimes2()
{
f(-18000);
}
生成的程序集是:
.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
.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
因此,我想这大概是人们最接近a的地方了。:-)
constepr
意味着const
const int
对于每个都足够了,但是constepr int
可能更明确。请不要将两者混用。不是每次调用函数时都会创建和销毁常量int,因此也必须进行计算吗?我知道它是可以优化的,但我想纠正它,这样代码就能准确地表达我的意思。@EddieV223这些变量是静态的它们不是为每个实例创建的