2017-02-21 163 views
2

我打電話給基於模板的函數共享一個函數和結構之間的類型。這段代碼有什麼問題?爲什麼我編譯時收到錯誤?std ::函數和錯誤:沒有匹配的函數調用

TEST.CPP

#include <functional> 
#include <iostream> 

template<typename T> 
struct mystruct 
{ 
    T variable; 
}; 

int myfunc(int x) 
{ 
    return 2*x; 
} 

template<typename T> 
T calculate(
    mystruct<T> custom_struct, 
    std::function<T(T)> custom_func) 
{ 
    return custom_func(custom_struct.variable); 
} 

int main() 
{ 
    mystruct<int> A; 
    A.variable=6; 
    std::cout<<calculate(A,myfunc)<<std::endl; 
    return 0; 
} 

編譯結果:

test.cpp:25:31: error: no matching function for call to ‘calculate(mystruct<int>&, int (&)(int))’ 
    std::cout<<calculate(A,myfunc)<<std::endl; 
          ^

回答

6

沒有理由使用std::function包裝。相反,使用一般的模板參數F

template<typename T, class F> 
T calculate(
    mystruct<T> custom_struct, 
    F custom_func) 
{ 
    return custom_func(custom_struct.variable); 
} 

Live Example

注意,你也忘了在調用點訪問variable成員。 由於您在此處進行泛型編程,因此您還希望返回類型等於T或甚至auto(C++ 14,對於C++ 11,您可能要使用decltype但這種重複太多)。

+0

我還要修復'int'返回類型 – user463035818

+0

@ tobi303是,更新 – TemplateRex

2
template<typename T> 
int calculate(
    mystruct<T> custom_struct, 
    std::function<T(T)> custom_func); 

編譯器將嘗試從std::function<T(T)>以及mystruct<T>演繹T,但是從函數指針扣失敗。一個解決辦法是通過使非推斷背景上std::function<T(T)>停用模板扣:

template <typename T> struct identity { using type = T; }; 
template <typename T> using identity_t = typename identity<T>::type; 

template<typename T> 
int calculate(
    mystruct<T> custom_struct, 
    identity_t<std::function<T(T)>> custom_func) 
{ 
    return custom_func(custom_struct.variable); 
} 

雖然這讓函數簽名有點醜陋,你仍然可以有T推斷,所以你可以叫calculate(A,myfunc)而比calculate<int>(A,myfunc)

但是,在這種情況下,您應該使用TemplateRex's solution,因爲std::function帶有一堆開銷,除非您想將它存儲在某處,否則實際上並不需要這些開銷。

1

您錯誤地將custom_struct轉換爲custom_funccalculate()

嘗試通過custom_struct.variable來代替:

template<typename T> 
int calculate(
    mystruct<T> custom_struct, 
    std::function<T(T)> custom_func) 
{ 
    return custom_func(custom_struct.variable); 
} 

同樣在ideone

3

你的代碼是有點亂,但總是孤單的解決方案。

#include <functional> 
#include <iostream> 

template<typename T> 
struct mystruct 
{ 
    T variable; 
}; 

const int myfunc(const int & x) 
{ 
    return 2*x; 
} 

template<typename T> 
T calculate(
    mystruct<T> custom_struct, 
    std::function<T(T)> custom_func) 
{ 
    return custom_func(custom_struct.variable); 
} 

int main() 
{ 
    mystruct<int> A; 
    A.variable=6; 
    std::cout<<calculate<int>(A,myfunc)<<std::endl; 
    return 0; 
} 

只是有一個問題,return custom_func(custom_struct),你已經到variable成員從結構傳遞,並添加calculate<int>代替calculate

你可以試試/測試這裏的新代碼:http://cpp.sh/33cpn

相關問題