是否可以在C++中推迟 const 变量的初始化,例如 Java 的"blank final"功能?
Is it possible to defer initialization of a const variable in C++, like Java's "blank final" feature?
在Java中,我们可以声明一个空白的final
变量,并在以后对其进行初始化。编译器将确保初始化只发生一次 - 初始化失败或双重初始化都是编译时错误。例如:
public int bar() {
return 66;
}
public void foo() {
final int x; // declare the variable
...
x = bar(); // initialization only once
}
在 Java 中,编译器可以保证x
在第一次赋值之前绝对不会在任何代码路径上赋值,并且可以保证绝对不会在任何代码路径上第二次赋值。(有关更多信息,请参见 Java 语言规范的第 16 章 "明确赋值"。
我们如何在C++中实现类似的行为?是否可以将变量声明为const
但推迟其初始化?(不丢弃const
说明符。
除非定义常量,否则无法初始化常量。你必须找到一种方法来知道它的价值在哪里被定义。如果x
的值难以确定,请考虑使用函数的结果,例如
const int x = calc_x();
或像这样的闭包
const int x = []() { /* code to calculate x's value */ }();
const
ness 是对象类型的一部分,对象类型在任何情况下都无法更改,因此要么x
const
,以后无法初始化它,要么根本不const
x
。
可以设计一个模拟此内容的包装器class
,但您最多只能得到运行时错误。
请注意,似乎有const_cast
形式的解决方案,但这假设所讨论的对象实际上不是const
。在const int x
的情况下,在初始化后无法合法地更改其值。
C++没有
内置功能。 不过,您可以自己构建它。 您可以创建一个类来保存所需类型的对象的存储,并且可以为此重载赋值运算符,以便只能调用和初始化一次。 那看起来像
template<typename T>
class once
{
private:
std::aligned_storage_t<sizeof(T), alignof(T)> data;
T* ptr = nullptr;
public:
once() = default;
~once()
{
if(ptr) // it is initialized so call the destructor
ptr->~T();
// optionally you can add
// throw("a once<T> must be initialized once");
// this can help to enforce that the object is actually initialized as you'll get a runtime exception in code that does not do so
}
template<typename U>
once& operator =(U&& value)
{
if (!ptr) // it is not initialized so call constructor
{
ptr = new(&data) T(std::forward<U>(value));
}
else
throw ("can only assign to a once<T> once.");
return *this;
}
operator const T&()
{
return *ptr;
}
};
然后你会像
int main()
{
once<int> foo;
if (1 < -1)
foo = 21;
else
foo = 42;
std::cout << foo;
//foo = 23; // uncomment this to get an exception.
}
相关文章:
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 将数字转换为字母(例如:123 转换为一二三)
- Visual studio代码重构似乎不起作用(例如,重命名符号-f2)
- 如何计算数据类型的范围,例如int
- 在java中解决这段代码时面临循环中的问题
- 尝试用java代码编译和运行c++代码
- 在这种情况下,java对象是否可以调用本机函数
- 在java中读取c++字节的位字段
- 为什么C++对链表中的下一个节点使用指针,而像 C# 或 Java 这样的语言只使用类 Node 的名称?
- 使用已使用 java 编码的 openssl 解码数据
- 这是否符合C++标准:双响双响,例如!!(-0.0).
- SWIG Java 在使用 -DSWIGWORDSIZE64 时将int64_t转换为 jlong
- 如何将CMSampleBufferRef/CIImage/UIImage转换为像素,例如uint8_t[]
- 任何C 字符串库,例如QString(或Java String)
- 是否可以在C++中推迟 const 变量的初始化,例如 Java 的"blank final"功能?
- 在Java中读取字符,例如C
- 如何通过代码(例如Java)将键按输入发送到浏览器中
- 高级语言(例如Java)和汇编语言之间的关系
- 捕获 Segfault 或任何其他错误/异常/信号C++例如在 Java 中捕获异常