如何在不允许临时创建的情况下编写 const ref

How to write const ref without allowing temporary creation

我希望能够提供采用现有给定类型常量引用对象的函数。

即我想要按常量引用但不创建临时文件。 [编辑这句话以澄清它!]

我想不出有什么方法可以直接用 C++ 表达:

1 void fn(const T & t)
如果存在(非显式)T(S),将从 S 创建一个临时 T

2 void fn(T & t)
将只允许非 const t 作为参数(我需要它也适用于 const t)。

3 void fn(T && t)
需要一个非常量 rvalue.

4 void fn(const T && t)
需要 const rvalue

有什么方法可以做到这一点 - 通过引用接受任何参数,const,而不允许创建临时文件?


失败的想法:

在不提供其他两个的情况下提供 #2 和 #4,现在我们有一个明确的 fn,它引用任何现有的 T(但不会静默生成临时文件) ?

不,这也不够,因为我还需要能够绑定到 const T & - 目标对象本身通过 const 引用传递给我们的调用者...


我想除了我可以控制 T 以确保它不提供隐式 T(S).

的情况外,我看不出有什么办法可以做到这一点

我是对的,还是我忽略了一些解决方案?

如果这是一个自由函数,那么您可以按照 nwp 的建议进行操作,并添加一个采用右值引用并将其删除的重载。

void fn(const SomeType& t)
{
    // stuff to do with const lvalue
}

void fn(SomeType&&) = delete; // compiler error if you give me an rvalue

之所以可行,是因为右值引用优于对 const 的引用。因此,当重载解析开始并且您传递一个临时值时,编译器将 select void fn(const T&&) 作为最佳匹配。之后它会看到该函数被删除,它会发出编译错误

从评论来看,您的实际问题似乎与右值和左值无关,而只是防止隐式转换。您可以通过将函数更改为函数模板,然后使用 sfinae 约束模板来实现:

template <class T, std::enable_if_t<std::is_same<std::decay_t<T>, CString>::value, int> = 0>
void fn(const T&) {

}

这仅在使用某种 CString 调用时有效,隐式转换为 CString 的类型将无效。

实例:http://coliru.stacked-crooked.com/a/80602c39cdc4d35e

也就是说,更好的解决方案是简单地更改这些函数以接受 string_view,它可以从各种字符串隐式构造,成本低廉。我不知道它是否处理 CString 或不,但你总是可以纠正你自己的。写起来相当简单class。 http://en.cppreference.com/w/cpp/string/basic_string_view