考虑这两个模板函数:
template<typename T>
void foo(T&& bar) {
// do stuff with bar, which may or may not be an instance of a templated class
}
template<typename U, template<typename> class T>
void foo(T<U>&& bar) {
// do stuff with bar, which must be an instance of a templated class
}
为什么前者接受左值(通过使用转发引用)而后者不接受?
看起来Can an identity alias template be a forwarding reference?也可能与此相关,但它似乎涵盖了转发引用限制的不同方面。
答案 0 :(得分:3)
如果要保留转发引用参数,并同时推断出参数的类型,可以使用以下解决方案:
$(document).ready(function(){
var a;
var b;
var correct = 0;
var wrong = 0;
display();
displayInt();
function displayInt() {
var disInt;
disInt = setInterval(display, 2000);
}
function display() {
a = Math.floor((Math.random()*3)+1);
$("#number1").html(a);
b = Math.floor((Math.random()*3)+1);
$("#number2").html(b);
}
function addScore() {
if (a == b) {
correct++;
$("#correctScore").html(correct);
} else {
wrong++;
$("#wrongScore").html(wrong);
}
}
$('input[type="button"]').click(function() {
a = $("#number2").html();
b = $("#number1").html();
addScore();
});
});
答案 1 :(得分:2)
因为标准说该语言应该如何运作。
[14.8.2.1] [temp.deduct.call]
3.如果P是cv限定类型,则类型推导将忽略P类型的顶级cv限定符。如果P是a 引用类型,P引用的类型用于类型推导。 转发参考是一个右值 引用cv-nonqualified模板参数。如果P是转发引用且参数是a 左值,类型“左值引用A”用于代替A进行类型扣除。
只有对CV非限定模板参数的右值引用才能以这种方式推断为l值引用。
要实现您要执行的操作,您可以使用特征提取模板模板参数。
#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&amp;的函数。和&amp;&amp;像往常一样。