因为这就是标准所说的语言应该如何工作的方式。
[14.8.2.1][temp.deduct.call]
3.如果 P 是 cv 限定类型,则忽略 P 类型的顶级 cv 限定符进行类型推导。如果 P 是引用类型,则使用 P 所引用的类型进行类型推导。转发引用是对 cv 非限定模板参数的右值引用。如果 P 是转发引用并且参数是左值,则使用类型“对 A 的左值引用”代替 A 进行类型推导。
以这种方式,只有对 CV 非限定模板参数的右值引用可以推断为左值引用。
为了实现您想要做的事情,您可以使用特征来提取模板模板参数。
#include <type_traits>
/***
* Extract template from template type.
*/
template <typename I> struct get_template;
template <template<class> typename T, typename C>
struct get_template<T<C>> {
template <typename U>
using temp = T<U>;
};
template <typename T> struct A{};
struct B;
template<typename W>
void foo(W && bar) {
typedef typename get_template<typename std::remove_reference<W>::type>::template temp<int> new_type;
new_type my_variable;
}
int main() {
A<B> temp;
foo(temp);
}
或者,像往常一样重载 const & 和 && 的函数。