次のC++コード例を検討してください。
namespace n
{
struct A {};
}
struct B {};
void foo(int) {}
template<typename T>
void quux()
{
foo(T());
}
void foo(n::A) {}
void foo(B) {}
int main()
{
quux<n::A>(); // Error (but works if you comment out the foo(int) declaration)
quux<B>(); // Works
return 0;
}
コメントに示されているように、テンプレートのインスタンス化quux<n::A>()
により、コンパイラエラーが発生します(GCC 4.6.3の場合)。
foo.cpp: In function ‘void quux() [with T = n::A]’:
foo.cpp:22:16: instantiated from here
foo.cpp:13:5: error: cannot convert ‘n::A’ to ‘int’ for argument ‘1’ to ‘void foo(int)’
誰かが私に何が起こっているのか説明できますか?と同じように機能することを期待していましたquux<B>()
。foo
依存していると見なされる場合、それは何かと関係があるに違いありません。残念ながら、私のC++fooは十分ではありません。宣言が存在しない場合、例は正常にコンパイルfoo(int)
されます。これも私にとっては驚くべきことです。
ヒント、説明、回避策は大歓迎です。
アップデート1:
foo(n::A)
の定義の前にの宣言を移動したくない(読み取ることができない)quux
(エラーを回避する)。
アップデート2:
テンプレートの前に宣言された間違った署名を持つ関数によって混乱している関連する質問テンプレート関数呼び出しを指摘してくれたDavidに感謝します。Johannes Schaubによって受け入れられた回答-litbはラッパークラスソリューションを提案します。これは、私の場合は回避策としても機能します。しかし、私はそれに100%満足しているわけではありません。
アップデート3:
foo(n::A)
の定義を名前空間に入れることで問題を解決しましたn
。規格の関連セクションを指摘するだけでなく、代替ソリューションも提供するJesseGoodとbames53の有益な回答に感謝します。DavidRodríguezに感謝します-私が提案された解決策と他のすべての貢献者を正しく理解していなかったときの彼の説明のためのdribeas。