单独定义模板类的模板成员

Defining a Template Member of a Template Class separately from the Declaration

本文关键字:成员 单独 定义      更新时间:2023-10-16
#include <cstdlib>
template<class A> struct Foo
{
    template<class B> static bool Bar();
};
template<class B> template<class A>  bool Foo<A>::Bar<B>()
{
    return true;
}
int main()
{
    bool b = Foo<int>::Bar<long>();
    b;
}

这会导致链接器错误:

main.obj : error LNK2019: unresolved external symbol "public: static bool __cdecl Foo<int>::Bar<long>(void)" (??$Bar@J@?$Foo@H@@SA_NXZ) referenced in function main

我需要在类模板声明之外定义这个成员函数。换句话说,我不能这样做:

#include <cstdlib>
template<class A> struct Foo
{
    template<class B> static bool Bar()
    {
        return true;
    }
};
int main()
{
    bool b = Foo<int>::Bar<long>();
    b;
}

我错过了什么?如何定义这个成员函数模板?需要什么语法?

注意:我正在使用MSVC 2008,以防相关。

编辑

我尝试的第一件事是颠倒template<class A>template<class B>的顺序:

#include <cstdlib>
template<class A> struct Foo
{
    template<class B> static bool Bar();
};
template<class A> template<class B>  bool Foo<A>::Bar<B>()
{
    return true;
}
int main()
{
    bool b = Foo<int>::Bar<long>();
    b;
}

这导致编译器错误:

.main.cpp(11) : error C2768: 'Foo<A>::Bar' : illegal use of explicit template arguments

Bar函数定义的右括号上

template<class B> template<class A>的顺序倒过来。第二个是"内部的",与成员声明一起使用。看到§14.5.2/1 .

同样,正如John指出的,从Bar<B>中删除参数列表。

// "outer" template: this parameter gets substituted to create "inner" template
template< class A >
// "inner" template stands alone after "outer" substitution
template< class B >
bool
// This will just be a class name after "outer" substitution.
      foo<A>
// This has usual function template syntax
             :: Bar() {

这个适合我:

template<class A>
template<class B>
bool Foo<A>::Bar()
{
    return true;
}

编写两个template说明符的顺序很重要(首先是外部模板)。此外,如果您实际将<B>放在函数模板的名称上,至少有一个编译器(GCC)认为您试图部分专门化函数Bar,这是不可能的。