我希望能够提供通过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)
。
我是对的,还是我忽略了一些解决方案?
答案 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