2013-03-17 43 views
12

我碰到一個問題,將一些代碼移植到MSVC中,令我感到困惑。據我所知,代碼應該是合法的,Clang編譯它就好了。爲什麼MSVC無法編譯這個模板函數?

我已經收窄到以下幾點:

enum E { 
    x 
}; 

template <typename T> 
struct traits { 
    static const E val = x; 
}; 

template <E e> 
struct S { 
    S(){}; 
}; 

template <typename T> 
S<traits<T>::val> foo(T t); 

int main() { 
    char c = 0; 
    foo(c); 
} 

注意,編譯後的代碼預計產量鏈接錯誤(我剝奪功能foo的定義保持樣品最小),但據我所知應該乾淨地編譯。

但是,MSVC給了我這個錯誤:

error C2893: Failed to specialize function template 'S::val> foo(T)'

所以我的問題:

  • 是MSVC在拒絕代碼正確的機會嗎? (如果是這樣,爲什麼?)
  • 如果沒有,任何人都可以縮小它做錯了什麼?如同它是否是一種他們根本沒有實現的語言特性(比如模板的兩階段名稱查找),或者「只是」他們聲稱支持的功能實現中的一個普通錯誤?

我轉載的問題上VC++ 2010和2012年

+0

與今天早些時候的這個問題有關嗎? [在類型推導之後,函數模板中的替換順序是否有任何保證?](http://stackoverflow.com/questions/15462336/is-there-any-guarantee-on-the-order-of-substitution- in-a-function-template-after) – 2013-03-17 21:58:32

+0

@BoPersson:似乎與我無關。在這裏,我想不出任何其他問題。順便說一句,它在GCC 4.7.2 – 2013-03-17 22:04:56

+0

上按預期工作。而且,如果用'int'代替'enum',錯誤就會消失。它似乎是一個與'枚舉'相關的錯誤 – 2013-03-17 22:05:36

回答

3

運行一些測試自己後,這似乎是在MSVC編譯器錯誤。雖然GCC可以正常工作,但當您嘗試在S< E e >返回的模板參數中使用traits<T>::val時,MSVC會給出神祕且無用的編譯器錯誤(與您問題中的錯誤相同)。

有趣的是,當你改變S< E e >來取代一個整數時,它就起作用了。考慮下面這個例子,等同於你有一些不同的命名:

enum E { 
    x 
}; 

template <typename T> 
struct traits { 
    static const E val = x; 
}; 

template <E e> 
struct S { 
    S(){}; 
}; 

template <typename T> 
S< traits<T>::val > tricky(T t) { 
    return S< traits<T>::val >(); 
}; 

int main() { 
    char thiskidwhowalksaround = 0; 
    S<x> s = tricky(thiskidwhowalksaround); 
} 

現在,我們只是改變一個單一的事情

template <int e> // int instead of E 
struct S { 
    S(){}; 
}; 

然後程序編譯(鏈接和運行)完美地適合我。如果您也將恢復到原來的,然後在E值直接傳遞,如:

template <typename T> 
S<x> tricky(T t) { 
//^here 
    return S<x>(); // <-- here 
}; 

然後程序編譯文件。 MSVC有它叮咬的灰塵在嘗試做以下問題:

traits<T>::val

其中val是任何一種枚舉。我99%肯定這是編譯器本身的一個缺陷。這似乎是非常完美的C++,所以我不能說GCC通過使原始代碼片段工作而做了錯誤或擴展-y。因此,我所能得到的最好結果是MSVC與同行相比缺乏編譯器的穩健性。

您可以在這裏停止閱讀,因爲現在我要花一點時間來咆哮有關MSVC編譯器。

begin<rant> 這並不是說VC++團隊是壞的,或者C++是壞的,但是從我搜集的編譯器團隊和標準庫的團隊在微軟 - 作爲寫作的時間 - 是微小相比其他部門。令我感到震驚的是,MS行業這樣一個基本而重要的語言和核心部分,其人力相對較少,無法跟上 - 在我短暫的一生中 - 我發現它是世界上最慢的移動標準之一。我當然不是要敲打在VC++團隊中工作的人,但是我深感困惑,爲什麼他們沒有更多的人努力讓C++不僅速度快,而且使編譯器的工作更好,並且與其他人一樣好產品領域。 end<rant>

+0

這確實是一個編譯器錯誤。我在[連接]上報告了它(https://connect.microsoft.com/VisualStudio/feedback/details/781537/failed-to-specialize-function-template#tabs),他們只是表示它將被修復爲「in Visual C++的下一個版本「......每當這是 – jalf 2013-03-22 19:45:02

+0

@jalf:Hurray ......!也許。 – 2013-03-22 21:09:49

相關問題