与声明分开定义模板类的模板成员

时间:2011-04-29 21:42:35

标签: c++ visual-studio-2008

#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函数定义的右大括号中。

2 个答案:

答案 0 :(得分:3)

只需颠倒template<class B> template<class A>的顺序即可。第二个是“内部”,并与成员声明一起使用。见§14.5.2/ 1。

另外,正如约翰所指出的那样,从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() {

答案 1 :(得分:2)

这对我有用:

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

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