Передача ссылки на шаблон перегрузки оператора вызова функции

У меня есть класс, который перегружает оператор вызова функции с помощью функции шаблона, например, так:

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 - Вывод адреса 'i'

0110F664 - Вывод адреса аргумента в шаблоне перегрузки

0110F738 - Вывод адреса аргумента через 'test'

Функция шаблона 'test' предназначена только для проверки.

Отладчик Visual Studio подтверждает, что он использует 'int' вместо 'int&' для перегрузки шаблона:

test_function_call.exe! Test:: operator () (int t) Строка 9 C++

Как я могу заставить его использовать ссылку вместо этого? Есть ли способ указать типы с помощью <> в операторе вызова функции шаблона?

2 ответа

Решение

Это потому, что в вашем случае cv-квалификаторы и ссылочные значения параметра отбрасываются при выполнении вывода типа шаблона. Пройти через 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
}

Вы можете использовать универсальную ссылку:

class Test
{
public:
    template<class T>
    void operator()(T&& t)
    {
        std::cout<<(&t)<<std::endl;
    };
};
Другие вопросы по тегам