是否可以通过const引用接受一个参数,而禁止转换,使临时不会传递? [英] Is it possible to take a parameter by const reference, while banning conversions so that temporaries aren't passed instead?

查看:128
本文介绍了是否可以通过const引用接受一个参数,而禁止转换,使临时不会传递?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有时候我们喜欢通过引用获取一个大的参数,并且如果可能的话,使参考const可以广告它是一个输入参数。但是通过使用引用const,编译器然后允许它自己转换数据,如果它是错误的类型。这意味着它不那么高效,但更令人担心的是,我认为我指的是原始数据;

Sometimes we like to take a large parameter by reference, and also to make the reference const if possible to advertize that it is an input parameter. But by making the reference const, the compiler then allows itself to convert data if it's of the wrong type. This means it's not as efficient, but more worrying is the fact that I think I am referring to the original data; perhaps I will take it's address, not realizing that I am, in effect, taking the address of a temporary.

调用 bar

#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);
}

传递轻量级只读引用的最安全的方法是什么?我很想创建一个新的引用类模板。

What's the safest way to pass a lightweight, read-only reference? I'm tempted to create a new reference-like template.

(显然, int long 是非常小的类型,但我已经抓住了更大的结构,可以转换到彼此,我不希望这是静默发生,当我采取一个const引用。有时,将构造函数标记为显式帮助,但这不是理想的)

(Obviously, int and long are very small types. But I have been caught out with larger structures which can be converted to each other. I don't want this to silently happen when I'm taking a const reference. Sometimes, marking the constructors as explicit helps, but that is not ideal)

更新:我想象一个系统,函数 X byVal(); X& byRef(); 和以下代码块:

Update: I imagine a system like the following: Imagine having two functions X byVal(); and X& byRef(); and the following block of code:

 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到临时或ref-to-a-copy当我认为我会传递一些轻量级,如ref-to-lvalue。这只是一个编码标准的事情 - 如果我真的想允许传递一个ref到一个临时,然后我会使用一个简单的 const X& 。 (我在这篇关于Boost的FOREACH 的文章很有用。)

That example is based on local variables, but I want it to also work with parameters. I want to get some sort of error message if I'm accidentally passing a ref-to-temporary or a ref-to-a-copy when I think I'll passing something lightweight such as a ref-to-lvalue. This is just a 'coding standard' thing - if I actually want to allow passing a ref to a temporary, then I'll use a straightforward const X&. (I'm finding this piece on Boost's FOREACH to be quite useful.)

推荐答案

(回答自己的问题,感谢这个

(Answering my own question thanks to this great answer on another question I asked. Thanks @hvd.)

简而言之,将函数参数标记为 volatile 意味着它不能绑定到右值。 (任何人都可以定义一个标准报价?暂时可以绑定到 const& ,但不是 const volatile& 显然,这是我得到的g ++ - 4.6.1(额外:查看这个扩展的评论流一些)

In short, marking a function parameter as volatile means that it cannot be bound to an rvalue. (Can anybody nail down a standard quote for that? Temporaries can be bound to const&, but not to const volatile & apparently. This is what I get on g++-4.6.1. (Extra: see this extended comment stream for some gory details that are way over my head :-) ))

void foo( const volatile Input & input, Output & output) {
}

foo(input, output); // compiles. good
foo(get_input_as_value(), output); // compile failure, as desired.

希望参数为 volatile 。所以我写了一个小包装到const_cast volatile 。所以foo的签名变为:

But, you don't actually want the parameters to be volatile. So I've written a small wrapper to const_cast the volatile away. So the signature of foo becomes this instead:

void foo( const_lvalue<Input> input, Output & output) {
}

其中包装器是:

template<typename T>
struct const_lvalue {
    const T * t;
    const_lvalue(const volatile T & t_) : t(const_cast<const T*>(&t_)) {}
    const T* operator-> () const { return t; }
};

只能从左值创建

任何缺点?这可能意味着我不小心误用了一个真正易变的对象,但是我之前从未使用过 volatile 。所以这是我的正确的解决方案,我想。

Any downsides? It might mean that I accidentally misuse an object that is truly volatile, but then again I've never used volatile before in my life. So this is the right solution for me, I think.

我希望在默认情况下使用所有合适的参数来做这个习惯。

I hope to get in the habit of doing this with all suitable parameters by default.

在ideone上演示

这篇关于是否可以通过const引用接受一个参数,而禁止转换,使临时不会传递?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆