Mal*_*ous 13 c++ constants idiomatic constexpr c++11
在C++ 11中定义简单常量值的最佳方法是什么,这样就没有运行时惩罚?例如:(不是有效代码)
// Not ideal, no type, easy to put in wrong spot and get weird errors
#define VALUE 123
// Ok, but integers only, and is it int, long, uint64_t or what?
enum {
Value = 123
};
// Could be perfect, but does the variable take up memory at runtime?
constexpr unsigned int Value = 123;
class MyClass {
// What about a constant that is only used within a class, so
// as not to pollute the parent namespace? Does this take up
// memory every time the class is instantiated? Does 'static'
// change anything?
constexpr unsigned int Value = 123;
// What about a non-integer constant?
constexpr const char* purpose = "example";
std::string x;
std::string metadata() { return this->x + (";purpose=" purpose); }
// Here, the compiled code should only have one string
// ";purpose=example" in it, and "example" on its own should not
// be needed.
};
Run Code Online (Sandbox Code Playgroud)
因为我被告知这是一个无用的问题,因为它背后没有背景,这是背景.
我正在定义一些标志,以便我可以这样做:
if (value & Opaque) { /* do something */ }
Run Code Online (Sandbox Code Playgroud)
它的值Opaque在运行时不会改变,所以只有在编译时才需要它才能让它在我的编译代码中结束.这些值也用在一个循环中,该循环对图像中的每个像素运行多次,所以我想避免运行时查找会降低它的速度(例如,内存访问以在运行时检索常量的值.)这不是'过早优化,因为算法目前需要大约一秒钟来处理图像,我经常有超过100个图像要处理,所以我希望它尽可能快.
既然人们说这是微不足道的而且不用担心它,我猜#define你的文字价值已经接近,所以也许这是避免"过度思考"这个问题的最佳选择?我想普遍的共识是你只希望没有人需要使用Opaque你想要使用的单词或其他常量?
Pot*_*ter 12
实际上,这比它看起来更棘手.
只是明确重申要求:
在C++中,表达式可以是lvalues或prvalues(在C++ 11和C之前,rvalues对应于相关概念).左值参考对象,因此它们可以在出现大号赋值表达式EFT-手侧.对象存储和左值是我们想要避免的.
你想要的是一个标识符或id-expression来评估prvalue.
目前,只有普查员才能这样做,但正如您所观察到的那样,他们会留下一些需要的东西.每个枚举声明引入一个新的,不同的类型,因此enum { Value = 123 };引入一个不是整数的常量,但它自己的唯一类型转换为int.这不是适合这项工作的合适工具,尽管它适用于工作.
你可以使用#define,但这是一个黑客,因为它完全避免了解析器.您必须使用所有大写字母命名,然后确保相同的全大写字母名称不用于程序中的任何其他内容.对于库接口,这种保证尤其繁重.
下一个最佳选择是函数调用:
constexpr int value() { return 123; }
Run Code Online (Sandbox Code Playgroud)
但是要小心,因为constexpr函数仍然可以在运行时进行评估.你需要跳过一个箍来表达这个值作为计算:
constexpr int value() {
/* Computations that do not initialize constexpr variables
(or otherwise appear in a constant expression context)
are not guaranteed to happen at compile time, even
inside a constexpr function. */
/* It's OK to initialize a local variable because the
storage is only temporary. There's no more overhead
here than simply writing the number or using #define. */
constexpr int ret = 120 + 3;
return ret;
}
Run Code Online (Sandbox Code Playgroud)
现在,你不能将常量称为名称,它必须是value().函数调用运算符可能看起来效率较低,但它是完全消除存储开销的唯一当前方法.
| 归档时间: |
|
| 查看次数: |
10763 次 |
| 最近记录: |