我有一个模板化的C ++类,其中一个成员函数还有一个模板。
我在我的代码中的两个地方调用它,其中一个工作,另一个产生一个非常令人困惑的错误,归结为下面的示例代码:
#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的有效实例一样。
编译器错了吗? (uccntu 12.04上的gcc 4.5.1)特别奇怪的是,这段代码在代码中的其他地方进行编译似乎是一个等效的调用(完整的东西有太多的依赖关系,无法在这里有意义地再现)。
答案 0 :(得分:2)
您应该更改do_work<>()
函数模板的模板参数的顺序,否则您的实例化确实不正确:
// template<typename OtherFoo, unsigned X> // This order is not appropriate.
// Let template parameters that
// cannot be deduced come first...
template<unsigned X, typename OtherFoo>
// ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
// THIS FIRST THEN THIS
void do_work(const OtherFoo* __restrict, float, Foo* __restrict) const
{
}
这是因为在以下函数调用中,您为第一个模板参数提供了显式参数:
foo->template do_work<123>(foo_2.get(), x, &out);