【发布时间】:2012-01-25 15:02:25
【问题描述】:
有时我们喜欢通过引用来获取一个大参数,并且尽可能将引用设为 const 以宣传它是一个输入参数。但是通过将引用设为 const,编译器随后允许自己转换类型错误的数据。这意味着它的效率不高,但更令人担忧的是我认为我指的是原始数据;也许我会拿它的地址,而没有意识到我实际上是在取一个临时地址。
此代码中对bar 的调用失败。这是可取的,因为引用的类型不正确。对bar_const 的调用也属于错误类型,但它会静默编译。这对我来说是不可取的。
#include<vector>
using namespace std;
int vi;
void foo(int &) { }
void bar(long &) { }
void bar_const(const long &) { }
int main() {
foo(vi);
// bar(vi); // compiler error, as expected/desired
bar_const(vi);
}
传递轻量级只读引用的最安全方法是什么?我很想创建一个类似引用的新模板。
(很明显,int 和 long 是非常小的类型。但是我已经发现了可以相互转换的较大结构。我不希望这种情况在我采取行动时悄悄发生const 引用。有时,将构造函数标记为显式会有所帮助,但这并不理想)
更新:我想象一个系统如下:想象有两个函数 X byVal(); 和 X& byRef(); 以及以下代码块:
X x;
const_lvalue_ref<X> a = x; // I want this to compile
const_lvalue_ref<X> b = byVal(); // I want this to fail at compile time
const_lvalue_ref<X> c = byRef(); // I want this to compile
该示例基于局部变量,但我希望它也可以使用参数。如果我不小心传递了 ref-to-temporary 或 ref-to-a-copy,而我想我会传递一些轻量级的东西,例如 ref-to-lvalue,我想得到某种错误消息。这只是一个“编码标准”——如果我真的想允许将 ref 传递给临时对象,那么我将使用简单的const X&。 (我发现this piece on Boost's FOREACH 非常有用。)
【问题讨论】:
-
您说将构造函数标记为显式“有帮助但并不理想”——理想的解决方案是什么?考虑一下 James Kanze 的回答。
-
非
explicit构造函数有其用途。例如,当按值传递事物时,或者使用A a; B b = a;之类的事物时。在特定情况下,将T&更改为const T&不仅仅是禁止修改。将const添加到引用中并不仅仅是禁止修改似乎有点不一致。 (我迟早会评论所有答案,它们都很有趣。)