是否可以将"const"变量与非"const"变量以及"const&"引用区分开来?
Is it possible to distinguish a `const` variable from a non-`const` one and from a `const&` reference?
假设我想创建自己的引用("智能指针"(类型,该类型保证始终引用不可变数据,而不仅仅是不可变查看的数据。换句话说,任何人都不能改变的数据,而不是不通过该特定引用。这并不容易,因为C++通常认为const
事物是可变访问事物的子情况,并且&
引用隐式转换为const &
,同样*
转换为const *
。
我们称之为类型:
template<typename T>
class ImmRef { ... };
我可以做的一件简单的事情是声明:
template<typename T>
struct Imm
{
const T value;
};
然后只允许从Imm
s或其他ImmRef
中创建ImmRef
。这里变量本身被声明为const
,所以不可能对它进行任何可变引用,它实际上是不可变的。(除非它在内部使用 mutable
,但由于我们对此无能为力,让我们忽略它。
这是有效的,但是为了更大的灵活性,更广泛的适用性以及与不知道我们Imm
类型的其他代码的兼容性,如果我们可以为任何const
声明的变量创建ImmRef
,那就更好了。但目前尚不清楚C++是否可以区分"声明为const
的变量"与"对变量的const
引用",甚至与"未声明为const
的变量"。
换句话说,这应该有效:
const int myConstNumber = 666;
ImmRef<int> myImmRef = immRef(myConstNumber);
但这不应该:
int myNumber = 666;
ImmRef<int> myImmRef = immRef(myNumber);
这不应该:
const int& myConstRef = myNumber;
ImmRef<int> myImmRef = immRef(myConstRef);
有什么黑暗模板魔法可以让我做到这一点吗?
无法
判断引用引用是指真实的const
对象。函数无法判断其参数是命名对象还是引用。
decltype
会具体告诉您名称属于const
对象(不是引用(,但该名称必须在范围内。此用法不能封装在模板中。
宏可以完成这项工作,如果你真的想要它:
#define MAKE_IMMREF( NAME ) ImmRef< decltype( NAME ) >{ NAME }
template<typename T>
struct ImmRef {
static_assert ( std::is_const< T >::value, "ImmRef requires a constant." );
T & ref;
};
演示。
相关文章:
- 在内存不足之前,我可以声明多少个 const 变量?
- 当设置为 const 变量时使用 nullptr
- 声明与 const 变量和成员函数相同的标识符
- const变量是否可以在具有默认值的参数中赋值(作为可选参数)
- 编译器在传递 const 变量时返回错误:模板参数不是常量表达式
- 在成员函数之间传递const变量为数组的索引
- 为什么静态常量字符 * const 变量在为左值时可绑定到右值引用参数
- C 编译器可以执行用于返回值的命名const变量的RVO
- 如何访问一系列const变量作为const数组
- C 错误C3892:您无法分配const变量
- 是否可以在C++中推迟 const 变量的初始化,例如 Java 的"blank final"功能?
- 为什么将FMTFLAG指定两次 - 作为枚举的一部分,而另一个实例为静态const变量
- 使用非const变量代替所需的const变量(C )
- 使用const变量时,非静态数据成员的使用无效
- 定义,初始化全局const变量是安全的吗?
- const vs non-const变量一旦分配就没有变化
- 为什么设置const变量(将以相同的值存储)会导致不同的结果
- CPP中的私有静态常规成员变量与const变量
- 在避免新分配的同时,const变量的复杂初始化
- 如何通过其地址更改const变量的值