【发布时间】:2016-02-16 17:49:17
【问题描述】:
所以我有以下功能:
void scan(std::istream& is, Handler& h);
我想用不同的方式来称呼它,比如:
scan(std::cin, Handler());
scan(std::ifstream("myfile"), myhandler);
编译器抱怨std::ifstream("myfile") 和Handler() 是作为非常量引用传递的右值,所以抱怨是合法的,但我该怎么办?
- 两个函数参数都不能为
const(istream在读取时被修改,并且处理程序在回调期间更改其状态)。 - 如果我将参数类型更改为右值引用(
&&),那么我将无法传递std::cin,有时我真的很关心myhandler的最终状态,因此我无法对它们应用std::move两者都没有。 - 原则上,我可以通过模板或
auto&&类型推导将参数作为通用引用,从而为左值和右值引用的所有可能组合重载此函数,但我无意为除我之外的其他类型重载此函数已经指定了。
还有其他选择吗?
在这样一个微不足道的例子中,整个移动语义不知何故阻碍了。
【问题讨论】:
-
std::ifstream("myfile")是一个临时值,为什么不简单地为它创建一个变量呢? -
这与移动语义无关。
-
template<class T>T& lvalue_ref(T&& x){return x;}然后稍后 -scan(lvalue_ref(ifstream()), lvalue_ref(Handler())) -
@mariusm 这是使用指针而不是引用的正当理由。您还可以在
switch/case块中创建变量,将它们放入范围块 ({})。 -
你为什么不constrain一个函数模板?
标签: c++ c++11 c++14 rvalue-reference type-deduction