在类定义之外定义显式专用类的成员函数

时间:2013-01-14 15:10:55

标签: c++

我看到与模板有关的错误(编译器是Visual Studio 2012),我不明白。这是代码,归结为要点:

// Templated class - generic 
template <typename T>
class Test
{
    public:
        void WorksFine() {} // Comiples and works as expected at runtime
        void Problem();     
};

// Templated class - expicit specialization for T = int.
template <>
class Test<int>
{
        public:
            void WorksFine() {} // Comiples and works as expected at runtime
            void Problem();
};

// The definition below compiles and works fine at runtime.
template<typename T> void Test<T>::Problem() {}


// The definition below gives error C2910.
template<> void Test<int>::Problem() {printf("In Test::Problem(int instantiation)\n");}

对于WorksFine方法,函数定义是里面显式专用的类定义,一切都很好。但对于Problem方法,当我在显式专用类定义之外定义方法时,我得到错误C2910

这是为什么?错误C2910表示问题是已定义Test :: Problem()。但是在类中没有 定义...没有函数定义只有声明。

根据您选择放置函数定义的位置,能够执行某些操作似乎相当蹩脚,我总是更多地考虑样式/语法,而不是功能/语义决策。我错过了什么吗?

3 个答案:

答案 0 :(得分:9)

您不需要template<>。只需写下:

void Test<int>::Problem() {printf("In Test::Problem(int instantiation)\n");}

成员专业化的template<>语法是必需的,只需在其自己的上显式实例化成员;在定义现有专业化的成员时省略它。

template<typename T> struct X { static int i; };
template<> int X<int>::i = 0;  // member instantiation, uses template<>

template<typename T> struct Y { static int i; };
template<> struct Y<int> { static int i; }  // template specialization
int Y<int>::i = 0;  // no template<>

答案 1 :(得分:0)

您在显式函数定义中不再需要templatevoid Test<int>::Problem() {printf("In Test::Problem(int instantiation)\n");}

在这种情况下,g ++提供了更好的错误消息error: template-id 'Problem<>' for 'void Test<int>::Problem()' does not match any template declaration

答案 2 :(得分:0)

试试这个:

// The definition below gives error C2910.
void Test<int>::Problem() 
{
    printf("In Test::Problem(int instantiation)\n");
}

int main()
{
    Test<int> hey; 

    hey.Problem(); 
    return 0;
};