我有一对这样定义的函数模板:
template<typename CollectionType>
Foo<CollectionType> f(const CollectionType& v)
{
return Foo<CollectionType>(v); // copies v into a member variable
}
template<typename CollectionType>
Foo<CollectionType> f(CollectionType&& v)
{
return Foo<CollectionType>(std::move(v)); // moves v into a member variable
}
如果我按如下方式调用 f
:
std::vector<int> v;
f(v);
VC++ 编译器支持 &&
重载,显然是因为它是 less specialized .我希望在这种情况下调用 const&
重载——&&
版本适用于 f(ReturnAVector())
等结构。有没有办法在不手动指定模板参数的情况下实现这一点?
经过相当多的努力,我想到了这个:
template<typename CollectionType>
Foo<CollectionType> f(const CollectionType& v)
{
return Foo<CollectionType>(v); // copies v into a member variable
}
template<typename CollectionType>
typename std::enable_if<std::is_rvalue_reference<CollectionType&&>::value,
Foo<typename std::remove_reference<CollectionType>::type>>::type
f(CollectionType&& v)
{
return Foo<CollectionType>(std::move(v)); // moves v into a member variable
}
但是哇;这真的是获得我想要的东西的最简单方法吗?
最佳答案
与:
std::vector<int> v;
f(v);
你调用f(std::vector<int>&)
所以
template<typename CollectionType>
Foo<CollectionType> f(CollectionType&& v)
是完全匹配(通用引用)CollectionType
是std::vector<int>&
而
template<typename CollectionType>
Foo<CollectionType> f(const CollectionType& v)
需要常量提升。
一个可能的解决方案是添加一个非 const 版本:
template<typename CollectionType>
Foo<CollectionType> f(CollectionType& v)
或转发您的论点,例如:
template<typename CollectionType>
Foo<typename std::remove_reference<CollectionType>::type>
f(CollectionType&& v)
{
return Foo<typename std::remove_reference<CollectionType>::type>(std::forward<CollectionType>(v));
}
关于c++ - 模板推导/重载决议有利于 T&& 而不是 const T&,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25938749/