接受lvalue和rvalue参数的函数 [英] Function that accepts both lvalue and rvalue arguments

查看:157
本文介绍了接受lvalue和rvalue参数的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法在C ++中编写一个接受lvalue和rvalue参数的函数,而不使它成为模板?



例如,假设我写了一个函数 print_stream istream 中读取,并将读取的数据打印到屏幕上。

我认为这样调用 print_stream 是合理的:

  fstream file {filename}; 
print_stream(file);

,如下所示:

  print_stream(fstream {filename}); 

但是如何声明 print_stream

如果我声明为

  void print_stream (istream& is); 

那么第二次使用将无法编译,因为右值不会绑定到非const常量引用



如果我声明为

  void print_stream(istream& & is); 

那么第一次使用将无法编译,因为左值不会绑定到右值引用。 p>

如果我声明为

  void print_stream(const istream& is) ; 

那么函数的实现将不能编译,因为你不能从 const istream



我无法使函数成为模板并使用通用引用,因为它的实现需要单独编译。



我可以提供两个重载:

  void print_stream istream& is); 
void print_stream(istream&& is);

并且第二个调用是第一个,但这似乎很多不必要的样板,发现每次我用这样的语义写一个函数时,必须这样做。非常不幸。



有更好的方法吗?

解决方案

除了提供两个重载或使你的函数成为一个模板,没有太多的选择。 / p>

如果你真的,真的需要一个(丑陋的)替代品,那么我想你唯一可以做的是接受一个 const& ,前提条件是你不能将 const - 限定类型的对象传递给它(你不想支持,反正)。该函数将允许丢弃引用的 const



但我会亲自写两个重载和定义一个在另一个,所以你做重复的声明,但不是定义:

  void foo X& x)
{
//这里的东西...
}

void foo(X& }


Is there a way to write a function in C++ that accepts both lvalue and rvalue arguments, without making it a template?

For example, suppose I write a function print_stream that reads from an istream and prints the data that was read to the screen, or something.

I think it's reasonable to call print_stream like this:

fstream file{"filename"};
print_stream(file);

as well as like this:

print_stream(fstream{"filename"});

But how do I declare print_stream so that both uses work?

If I declare it as

void print_stream(istream& is);

then the second use won't compile because an rvalue will not bind to a non-const lvalue reference.

If I declare it as

void print_stream(istream&& is);

then the first use won't compile because an lvalue will not bind to an rvalue reference.

If I declare it as

void print_stream(const istream& is);

then the function's implementation won't compile because you can't read from a const istream.

I can't make the function a template and use a "universal reference", because its implementation needs to be separately compiled.

I could provide two overloads:

void print_stream(istream& is);
void print_stream(istream&& is);

and have the second call the first, but that seems like a lot of unnecessary boilerplate, and I would find it very unfortunate to have to do that every time I write a function with semantics like this.

Is there something better I can do?

解决方案

There is not much of a sane choice other than offering two overloads or making your function a template, I would say.

If you really, really need an (ugly) alternative, then I guess the only (insane) thing you can do is to have your function accept a const&, with a pre-condition saying that you cannot pass an object of a const-qualified type to it (you don't want to support that anyway). The function would then be allowed to cast away the constness of the reference.

But I'd personally write two overloads and define one in terms of the other, so you do duplicate the declaration, but not the definition:

void foo(X& x) 
{ 
    // Here goes the stuff... 
}

void foo(X&& x) { foo(x); }

这篇关于接受lvalue和rvalue参数的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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