假设我想创建自己的引用("智能指针")类型,保证始终引用不可变数据,而不仅仅是不可见的数据。换句话说,任何人都不能突变的数据,而不是仅通过该特定参考。这并不容易,因为C ++通常会将const
事物视为可变访问事物的子案例,而&
引用会隐式转换为const &
,同样*
转换为const *
{1}}。
我们称之为:
template<typename T>
class ImmRef { ... };
我能做的一件简单事就是声明:
template<typename T>
struct Imm
{
const T value;
};
然后只允许从ImmRef
或其他Imm
创建ImmRef
。这里变量本身被声明为const
,因此它不可能对它进行任何可变引用,实际上它实际上是不可变的。 (除非它在内部使用mutable
,但由于我们无法做到这一点,所以请忽略它。)
虽然有效,但为了获得更大的灵活性,更广泛的适用性以及与我们对Imm
类型无关的其他代码的兼容性,如果我们可以创建ImmRef
s会更好到任何 const
- 声明的变量。但是,目前还不清楚C ++是否能够区分一个声明为const
&#34;的变量。来自&#34; const
对变量&#34;的引用,甚至来自&#34;未声明为const
&#34;的变量。
换句话说,这应该有效:
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);
是否有任何黑暗模板魔法让我这样做?
答案 0 :(得分:1)
没有办法告诉引用引用真正的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;
};