У меня есть класс, который перегружает оператор вызова функции с помощью функции шаблона, например, так:
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 ++
Как я могу заставить его использовать ссылку вместо этого? Есть ли способ указать типы, используя <> по шаблону оператора вызова функции?
Это потому, что в вашем случае 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;
};
};