c++ - 模板推导/重载决议有利于 T&& 而不是 const T&

标签 c++ templates universal-reference

我有一对这样定义的函数模板:

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)

是完全匹配(通用引用)CollectionTypestd::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/

相关文章:

c++ - C++ 模板函数的行为

c++ - 优化执行时间

c++ - 如何从自定义数组中删除元素

c++ - 从字符串中获取行(不是从字符串流中获取)

c++ - 缺少类模板 "Complex"的参数列表

c++ - 为什么基于范围的 for 语句通过 auto&& 获取范围?

c++ - 将元素从 std::vector<T1> move 到 std::vector<std::pair<T1,T2>>

类和指针的 C++ 类型转换

c++ - GCC 无法使用 init-capture 捕获 'this' 指向模板类型的指针

c++ - C++11中函数参数的显式模板函数参数规范和隐式转换