将参数从模板转发到不同类型的函数

时间:2017-09-06 21:02:58

标签: c++

我正在尝试模板和转发。写了一些令我惊讶的简单实验代码。我想更好地理解这种机制,可能我在这里缺乏一些知识,因此我寻求帮助。你能解释一下为什么下面代码中的两个调用都不能编译(PLACE 2和3)吗?

#include <iostream>
#include <memory>
#include <utility>
using namespace std;

void h2rvalref(int&& i) { cout << "h2rvalref" << endl; }
void h2ref(int& i) { cout << "h2ref" << endl; }
void h2val(int i) { cout << "h2val" << endl; }

template <class T, class X>
void h1(T&& t, X x) { x(forward<T>(t)); }

int main()
{    
    // PLACE (1)
    h1<int, decltype(h2rvalref)>(1, h2rvalref);

    auto b = 1;
    // PLACE (2)
    // h1<int, decltype(h2ref)>(b, h2ref); // --> ERROR - no matching function..., cannot convert 'b' (type 'int') to type 'int&&'

    // PLACE (3)
    // h1<int, decltype(h2val)>(b, h2val); // --> ERROR - no matching function..., cannot convert 'b' (type 'int') to type 'int&&'
}

我不明白为什么错误说明将int转换为int&amp;&amp;当我有int类型的值b。

1 个答案:

答案 0 :(得分:1)

问题是您要为函数提供显式模板参数。当您明确提供要转发的类型的模板参数时,转发参数不起作用(除非您确实知道自己在做什么)。

template <class T, class X>
void h1(T&& t, X x) { x(forward<T>(t)); }

当你写h1<int, decltype(h2ref)>时,你得到一个这样的函数:

void h1(int&& t, decltype(h2ref) x) { x(forward<int>(t)); }

int&&是与int不同的类型,不能绑定到int类型的左值,例如您传入的b;它只能绑定到int

类型的右值

如果你不使用模板参数,它就可以了:

h1(b, h2ref);

这将实例化一个如下所示的函数:

void h1(int& t, // int& && collapses to just int&
        decltype(h2ref) x) {
    x(forward<int&>(t));
}