转发参考和模板模板

时间:2016-02-27 05:52:04

标签: c++ c++11 template-templates template-function forwarding-reference

考虑这两个模板函数:

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?也可能与此相关,但它似乎涵盖了转发引用限制的不同方面。

2 个答案:

答案 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();

    });    
});

DEMO

答案 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;像往常一样。