传递对模板函数的引用调用操作符重载

时间:2015-05-22 17:54:09

标签: c++ visual-studio-2013 operator-overloading windows-8.1 function-call-operator

我有一个类,它使用模板函数重载函数调用操作符,如下所示:

class Test
{
public:
    template<class T>
        void operator()(T t)
    {
        std::cout<<(&t)<<std::endl;
    };
};

我想用引用参数调用它,但是在尝试这样做时,它会将参数作为值传递。这是我的测试设置:

template<class T>
    void test(T t) {std::cout<<(&t)<<std::endl;}

int main(int argc,char *argv[])
{
    Test t;
    int i = 5;
    std::cout<<(&i)<<std::endl;
    t((int&)i); // Passes the argument as a value/copy?
    test<int&>(i); // Passes the argument as a reference
    while(true);
    return 0;
}

输出结果为:

  

0110F738 - 输出&#39; i&#39;

     

0110F664 - 模板重载中参数地址的输出

     

0110F738 - 通过&#39; test&#39;

输出参数的地址

模板功能&#39;测试&#39;仅用于验证。

visual studio调试器确认它正在使用&#39; int&#39;而不是&#39; int&amp;&#39;对于模板重载:

  

test_function_call.exe!Test :: operator()(int t)第9行C ++

如何强制它使用引用呢?有没有办法使用&lt;&gt;指定类型?在模板函数调用操作符上?

2 个答案:

答案 0 :(得分:2)

那是因为在你的情况下,执行模板类型推导时会丢弃cv-qualifiers和参数的reference-ness。通过std::ref包装来代替

t(std::ref(i));

简单示例:

#include <iostream>
#include <functional>

template<typename T>
void f(T param)
{
    ++param;
}

int main()
{
    int i = 0;
    f(std::ref(i));
    std::cout << i << std::endl; // i is modified here, displays 1
}

答案 1 :(得分:1)

您可以使用通用参考:

class Test
{
public:
    template<class T>
    void operator()(T&& t)
    {
        std::cout<<(&t)<<std::endl;
    };
};