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

时间:2017-03-30 15:23:06

标签: c++ parameter-passing pass-by-reference temporary-objects

我希望能够提供通过const引用获取给定类型现有对象的函数。

即。我想通过-const-ref-but-no-temporaries创建。 [编辑了这句话以澄清它!]

我无法想出用C ++直接表达的方式:

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

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

3 void fn(T && t)
需要非const rvalue

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

有没有办法做到这一点 - 通过引用接受任何参数,const,而不允许创建temp?

失败的想法:

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

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

我想我认为无法实现此目的,除非我可以控制T以确保它不提供隐式T(S)

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

2 个答案:

答案 0 :(得分:3)

如果这是一个免费功能,那么您可以按照nwp的建议进行操作,并添加一个带有右值引用并删除它的重载。

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

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

这是有效的,因为rvalue引用优先于const的引用。因此,当重载决策启动并且您传递临时时,编译器将选择void fn(const T&&)作为最佳匹配。之后,它将看到该函数被删除,并将发出编译器错误

答案 1 :(得分:3)

从评论来看,似乎你的实际问题与rvalues和lvalues无关,而只是阻止了隐式转换。您可以通过将函数更改为函数模板,然后使用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,但你可以随时对待自己。这是一个相当简单的写作课程。 http://en.cppreference.com/w/cpp/string/basic_string_view