11

我看到一个我不理解的与模板相关的错误(编译器是 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 方法,函数定义显式专门化的类定义中,一切正常。但是对于问题方法,当我在明确专门的类定义之外定义方法时,我得到错误 C2910

为什么是这样?错误 C2910 表明问题在于 Test::Problem() 已定义。但它没有在类内部定义......没有函数定义只有一个声明。

根据您选择放置函数定义的位置,是否能够做某事似乎很蹩脚,我一直认为这更像是一种风格/语法决定,而不是功能/语义决定。我错过了什么吗?

4

3 回答 3

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<>
于 2013-01-14T15:14:38.213 回答
0

您不再需要template显式函数定义:void 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

于 2013-01-14T15:16:06.613 回答
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;
};
于 2013-01-14T15:19:14.917 回答