テンプレート化されたC++クラスがあり、そのメンバー関数の1つにさらにテンプレートがあります。
私はそれを私のコードの2つの場所で呼んでいます。1つは機能し、もう1つは非常に紛らわしいエラーを生成します。これは以下のサンプルコードに要約されます。
#include <memory>
template <unsigned char N>
struct Foo
{
template <typename OtherFoo, unsigned X>
void do_work (
const OtherFoo * __restrict,
float,
Foo * __restrict
)
const
{
}
};
struct Bar
{
std :: unique_ptr <Foo<0>> foo_0;
std :: unique_ptr <Foo<1>> foo_1;
std :: unique_ptr <Foo<2>> foo_2;
void run (float);
template <typename FOO>
void run (std :: unique_ptr <FOO> & foo, float x)
{
FOO out;
foo -> template do_work <123> (foo_2.get(), x, &out);
}
};
void Bar :: run (float x)
{
if (foo_0)
run (foo_0, x);
else
run (foo_1, x);
}
int main ()
{
Bar bar;
bar .run (1.23);
}
エラーメッセージは非常に単純ですが、明らかに間違っています。
temp.cpp: In member function ‘void Bar::run(std::unique_ptr<FOO>&, float) [with FOO = Foo<0u>]’:
temp.cpp:61:16: instantiated from here
temp.cpp:54:3: error: no matching function for call to ‘Foo<0u>::do_work(Foo<2u>*, float&, Foo<0u>*)’
temp.cpp: In member function ‘void Bar::run(std::unique_ptr<FOO>&, float) [with FOO = Foo<1u>]’:
temp.cpp:63:16: instantiated from here
temp.cpp:54:3: error: no matching function for call to ‘Foo<1u>::do_work(Foo<2u>*, float&, Foo<1u>*)’
見てみましょう、Foo<1u>::do_work(Foo<2u>*, float&, Foo<1u>*)
...を呼び出すための一致する関数はありませんか?いいえ、それは私にはFoo::do_workの有効なインスタンス化のように見えます。
コンパイラは間違っていますか?(ubuntu12.04のgcc4.5.1)特に奇妙なのは、このコードがコードの他の場所で同等の呼び出しのように見えるものでコンパイルされることです(完全なものには依存関係が多すぎてここで意味のある再現ができません)。