2014-02-07 37 views
4

我有一些爲Clang 3.2寫的代碼,我試圖在VC++ 12中運行端口。 Clang 3.2+和GCC 4.8沒有問題,但VC++ 12抱怨。下面是產生這一問題的最小片段:解決VC++ 12中的模板專業化錯誤?

template <int(*ptr)()> 
class foo {}; 

template<int N> 
int ReturnsN() { return N; } 

template<int N> 
class bar { 
    typedef foo<ReturnsN<N>> fooN; 
}; 

現在,我敢肯定這是一個編譯器缺陷(但請讓我知道,如果它是不是!)給出的錯誤是:

'specialization' : cannot convert from 'int (__cdecl *)(void)' to 'int (__cdecl *)(void)' 

那麼有沒有人知道一個體面的工作?看來編譯器確信專業功能沒有完全定義。

編輯:我也應該注意我已經試過這個股票編譯器和2013年11月的CTP。兩者都有同樣的問題。

+0

我很想知道是否刪除了'inline'會有什麼不同。 – WhozCraig

+0

@WhozCraig哦,對不起,它沒有。我認爲它做到了,並將其從我的測試項目中留下。將編輯我的問題。 –

+1

我假設你也嘗試過'foo <&ReturnsN>'也? (如果有效的話,我現在開始銷售我的MS股票)。 (另外,我在這裏沒有看到專業化,只是實例化)。 – WhozCraig

回答

3

一個悲傷的解決辦法,我建議你提交錯誤報告connect

template < int (*)() > 
class foo {}; 

template<int N> 
int ReturnsN() { return N; } 

template<int N> 
class bar { 
    static int myReturnsN() { return ReturnsN<N>; } 
    using fooN = foo<myReturnsN>; 
}; 
+0

我剛剛找到相同的解決方法!我會給你點,謝謝你的幫助。 [這裏也是錯誤報告。](https://connect.microsoft.com/VisualStudio/feedback/details/816952/specialization-of-function-template-cannot-be-passed-as-template-parameter) –

+1

VS2013生病了......而且這一個甚至與C++ 11支持如花式參數包擴展都沒有關係...... – galop1n

3

萬一有人好奇,我發現了一個有點難看的解決方法。基本上只需要添加一個靜態成員函數混淆的功能,所以它不會嘗試解析函數的專業化,同時也解決了函數指針模板參數:

template <int(*ptr)()> 
class foo {}; 

template<int N> 
int ReturnsN() { return N; } 

template<int N> 
class bar { 
private: 
    static int Hack() { 
    return ReturnsN<N>(); 
    } 
public: 
    typedef foo<Hack> fooN; 
}; 

這將編譯所有VS2012,VS2013和VS2013十一月CTP。

0

另一種可能的解決方法是使類模板的ReturnsN功能靜態成員函數:

template <int(*)()> 
class foo; 

template <int N> 
struct Wrapper { 
    static int ReturnsN() { return N; } 
}; 

template <int N> 
class bar { 
    typedef foo<Wrapper<N>::ReturnsN> fooN; 
}; 

此代碼用VC++ 2013編譯得很好。