讓我們以下面的例子程序:不正確的重載
#include <cmath>
namespace half_float
{
template<typename T> struct half_expr {};
struct half : half_expr<half>
{
operator float() const;
};
template<typename T> half sin(const half_expr<T>&);
template<typename T> half atan2(const half_expr<T>&, const half_expr<T>&);
}
using namespace std;
using half_float::half;
int main()
{
half a, b;
half s = sin(a);
half t = atan2(a, b);
}
在VS 2010這個編譯就好(忽略了明顯的鏈接錯誤,現在)。但在VS 2012這給了我:
錯誤C2440: '轉換':不能從 '浮動' 轉換爲 'half_float ::一半'
如此看來重載解析沒有按」 t從名稱空間half_float
(ADL應該完成)中挑選版本,但從std
使用隱式轉換爲float
的版本。但奇怪的是,這隻發生在atan2
呼叫而不是sin
呼叫。
在較大的項目中,實際上首次發生此錯誤時,對於其他雙參數函數(或具有2 half
參數的參數)也會出現此錯誤,如fmod
,但不適用於任何單參數函數。同樣在較大的項目中,它也可以正常工作gcc 4.6/4.7和鏗鏘3.1沒有錯誤,雖然我沒有明確測試這個SSCCE版本。
所以我的問題是,是VS 2012身邊這個錯誤的行爲(因爲它僅發生於和僅2個參數的功能),還是我負責一些細微之處的過載分辨率規則(我猜可能確實會有點棘手)?
編輯:它還如果我直接using namespace half_float
或者直接把整個事情的全局命名空間中發生的。同樣,如果我不是using namespace std
,也會發生這種情況,但這是VS-實現將數學函數放入全局名稱空間。
編輯:它與原來的VC 2012編譯器中,都有發生,以及在2012年11月CTP它。
編輯:雖然我不能完全肯定這是真的違反了嚴格意義上的標準,我已經申請根據我的回答結果爲它bug,因爲它至少是不一致1參數函數的定義,並值得VS -Team進一步調查。
VS2012似乎有錯誤。 – Nawaz
我同意Nawaz。這在我的Apple LLVM 4.1工具鏈中沒有問題地編譯出來。它也適用於VS2010有點說明問題。你用CTP試過了嗎? – WhozCraig
@WhozCraig不,好主意,很快就會嘗試。 –