2013-12-23 8 views
8

この正しい動作であるかどうかを理解するのに役立つ人がいますか?char *とchar [N]のあいまいなエラー

この例で考えてみましょう:GCCで

#include <iostream> 
using namespace std; 

template <typename T> 
struct test { 
}; 

template <typename T> 
bool operator==(const test<T>& obj, const T* arr) { 
    return true; 
} 

template <typename T, size_t TN> 
bool operator==(const test<T>& obj, const T (&arr)[TN]) { 
    return false; 
} 

int main() { 
    cout << (test<char>() == "string") <<endl; 
    return 0; 
} 

は、予想通り、それはうまくコンパイルし、 '0' を出力4.7.3。

しかし、Visual Studioコンパイラでは、ambiguous error (C2593)が報告されます。

この状況では、誰が正しいのですか。standardはそれについて何と言いますか?

ありがとうございます。

+1

曖昧ですと思います。 – Shoe

答えて

4

gccclangのかなり新しいバージョン(つまり、開発ブランチの最近のヘッド)もあいまいさを示しています。私は、配列を取っているオーバーロードが良いと思ったでしょうが、コードがあいまいであるようです。私は、しかし、規格の関連条項を追跡していない。

+2

+1 14.8.2.4 '[temp.deduct.partial]'と14.5.6.2 '[temp.func.order]'によって動かされていると確信しています。標準のそれらのセクションを言うためには、 "肉質"は叙事詩的な割合の総体的な控えめなものになるでしょう。それほど私は似たような質問に実際に足を踏んで(今は思い出すことができません)、あなたが正しいと信じて+1しました。 – WhozCraig

+3

重要な点は、アイデンティティと配列からポインタへの変換のランクが同じであることです。*完全一致*なので、変換シーケンス(変換/配列からポインタへの変換なし)はどれも他より悪くありません。 –

1

単純なオーバーロードはgccの新しいバージョンではうまくいかず、VC10ではうまくいきません。

誰かがここでこの問題を解決する方法を疑問に思うのであれば、解決策です:

template <typename T> 
struct test { 
}; 

template <typename T> 
struct parse { 
}; 

template <typename T> 
struct parse<T*> { 
    static bool run() { 
     return true; 
    } 
}; 

template <typename T, size_t TN> 
struct parse<T[TN]> { 
    static bool run() { 
     return false; 
    } 
}; 

template <typename T, typename T2> 
bool operator==(const test<T>& obj, const T2& obj2) { 
    return parse<T2>::run(); 
} 

int main() { 
    cout << (test<char>() == "string") <<endl; 
    cout << (test<char>() == (char*)"string") <<endl; 
    return 0; 
} 

はVC10、GCC-4.6.3とgcc-4.8.1とそれをコンパイル。 正しく動作しているようです。

関連する問題