2014-09-03 61 views
9

Tdouble(float)const當我嘗試使用function<T>時出現此錯誤。trait從成員函數類型中刪除const?

implicit instantiation of undefined template 'std::function<double (float) const>' 

但它的確定,當Tdouble(float)。我試圖使用std:: remove_cv<T>::type刪除這const,但這是行不通的。是的,我有#include<functional>

所以我的主要問題是:如何解決這個問題,並刪除const,以便我可以把這個函數類型放入std:: function


我碰到這個問題與lambda表達式的operator()方法工作的時候,但我認爲這個問題一般是有關的任何方法類型,而不是隻爲lambda表達式


但我的第二個問題是: double(float)const甚至意味着什麼?我可以理解

double (ClassName::) (float) const 

因爲這意味着成員函數不能修改其ClassName對象。當我將這種類型放入模板中去除類別類型時,我得到了導致問題的double(float)const

template<typename> 
struct DropClassType; 
template<typename Sig, typename C> 
struct DropClassType<Sig (C::*)> { 
    typedef Sig type_without_class; 
}; 

(鐺3.4.2從克將錯誤++ - 4.9.1更隱蔽,但基本上是相同的)

回答

10

爲什麼我得到的錯誤「未定義模板隱式實例化」?

std::function被定義爲一個未定義的基本模板和一個偏特匹配 「正常」 的函數類型(§20.9.11.2[func.wrap.func]):

template<class> class function; // undefined 
template<class R, class... ArgTypes> 
class function<R(ArgTypes...)> { /* ... */ }; 

double (float) const不匹配R(ArgTypes...),所以你得到未定義的基本模板。


如何解決這一問題,並刪除常量,這樣我可以把這個功能類型爲std::function

標準偏特化技巧。雖然我們在這,但我們也刪除volatile

template<class> class rm_func_cv; // undefined 
template<class R, class... ArgTypes> 
class rm_func_cv<R(ArgTypes...)> { using type = R(ArgTypes...); }; 
template<class R, class... ArgTypes> 
class rm_func_cv<R(ArgTypes...) const> { using type = R(ArgTypes...); }; 
template<class R, class... ArgTypes> 
class rm_func_cv<R(ArgTypes...) volatile> { using type = R(ArgTypes...); }; 
template<class R, class... ArgTypes> 
class rm_func_cv<R(ArgTypes...) const volatile> { using type = R(ArgTypes...); }; 

該方法亦可用於去除當然REF-限定符,。


是什麼double (float) const即使是什麼意思?!

這是一個比較隱祕的標準角落(§8.3.5[dcl。FCT]/P6):

函數類型與CV限定符SEQREF-限定符(包括 由的typedef名(7.1.3命名一個類型,14.1) )應僅顯示爲:

  • 用於非靜態成員函數的函數類型,
  • 功能類型到一個指針構件是指,
  • 的函數typedef聲明或別名聲明的頂級功能類型,
  • 型-ID類型參數(14.1)的默認參數,或
  • 的類型-ID模板參數對於類型參數(14.3.1)。

[

typedef int FIC(int) const; 
    FIC f; // ill-formed: does not declare a member function 
    struct S { 
     FIC f; // OK 
    }; 
    FIC S::*pm = &S::f; // OK 

- 端示例]

總之,它基本上是 「半類型」,可以使用來聲明類的成員函數或指向成員類型的指針(或作爲模板參數傳遞)。

+0

酷。所以它並不意味着任何「獨立」的東西,但是當你重新關聯一個類時,它就會變得有意義,就像你給出的兩個例子一樣。有沒有一個標準的特徵去除const? – 2014-09-03 22:00:16

+0

@AaronMcDaid我不知道任何。這是足夠模糊的,我懷疑任何人想寫它的特質。 – 2014-09-03 22:01:28

+1

我認爲這將不會因爲lambdas而變得模糊。這使我可以編寫一個函數,它將使用任何(非泛型)lambda或類似對象,並自動將其轉換爲一個'std :: function'對象。簡單地在lambda上運行'decltype(&T :: operator())'會返回一個類型,但需要從該類型中移除類型和這個奇怪的'const'。謝謝! – 2014-09-03 22:27:04

6
#include <functional> 

template <typename T> 
struct function_remove_const; 

template <typename R, typename... Args> 
struct function_remove_const<R(Args...)> 
{ 
    using type = R(Args...); 
}; 

template <typename R, typename... Args> 
struct function_remove_const<R(Args...)const> 
{ 
    using type = R(Args...); 
}; 

int main() 
{ 
    std::function<function_remove_const<double(float)const>::type> f; 
} 

Live demo link.