1

我有重載函數調用操作符與模板功能,像這樣一類:傳遞到模板函數調用操作符重載參考

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 - 模板參數的地址的輸出 - 「我」

0110F664地址的輸出過載

0110F738 - 參數的通過 '測試'

地址的輸出

模板函數'test'僅用於驗證。

Visual Studio調試證實,它使用 '詮釋',而不是 '廉政&' 爲模板超載:

test_function_call.exe測試::運算符()(INT T)9號線C++

我該如何強制它使用引用呢?有沒有辦法在模板函數調用操作符上使用<>來指定類型?

+1

你想'void運算符()(續T&T)' –

+1

我通過std::ref包裝,而不是

t(std::ref(i)); 

簡單示例轉發不希望它是'常量',我仍然需要能夠修改值。 – Silverlan

回答

2

這是因爲在您的情況下,執行模板類型推演時會放棄參數的cv限定符和參考性。

#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 
} 
+0

不知道std :: ref,但行爲不會改變,它仍然將它作爲一個值傳遞。 – Silverlan

+0

@Silverlan你怎麼知道?如果你願意,它會「模仿」引用傳遞。修改'operator()'中的't'。在裏面做'++ t',你會看到'i'會被修改。 – vsoftco

+1

這種模擬不是真實的 - 有很多方法可以區分'T&'和'std :: reference_wrapper '。 – Puppy

1

您可以使用通用的參考:

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

我仍然可以通過這種方式將它作爲值/副本傳遞嗎?我希望能夠做到。 – Silverlan

+2

@Silverlan不是真的,'t'的類型將被推斷爲'T&'或'T',它在[引用崩潰](http://thbecker.net/articles/rvalue_references/section_08.html)後成爲' T&'和'T &&'。 – vsoftco

相關問題