模板扣除/重载分辨率有利于T& over const T& [英] Template deduction/overload resolution favors T&& over const T&

查看:183
本文介绍了模板扣除/重载分辨率有利于T& over const T&的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一对定义的函数模板,如下:

I have a pair of function templates defined like so:

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 ++编译器支持&& overload,显然是因为不太专业化。我想在这种情况下调用 const& 重载 - && 例如 f(ReturnAVector())。有没有办法实现这一点,而无需手动指定模板参数?

The VC++ compiler favors the && overload, apparently because it is less specialized. I would like the const& overload to be called in this case--the && version is intended for constructions like f(ReturnAVector()). Is there a way to achieve this without manually specifying the template argument?

经过相当多的努力,我想出了这一点:

After a fair amount of effort, I came up with this:

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>& / code> so

you call f(std::vector<int>&) so

template<typename CollectionType>
Foo<CollectionType> f(CollectionType&& v)

是完全匹配(通用引用) CollectionType std :: vector< int>&
,而

is an exact match (universal reference) CollectionType is std::vector<int>& whereas

template<typename CollectionType>
Foo<CollectionType> f(const CollectionType& v)

需要const促销。

一个可能的解决方案是添加一个版本非const:

A possible solution is to add a version non const:

template<typename CollectionType>
Foo<CollectionType> f(CollectionType& v)

或转发您的参数,例如:

or to forward your argument, something like:

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));
}

这篇关于模板扣除/重载分辨率有利于T&amp; over const T&amp;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆