2

考虑以下 c++ 代码:

template <int K>
struct KData
{
   float data[K];
};

template<int K>
class KClass
{
public:   
    typedef KData<K> Data;
    Data m_data;

    Data square()
    {
        Data result;
        for(int i = 0; i < K; ++i)
            result.data[i] = m_data.data[i] * m_data.data[i];
        return result;
    }
    
    // Specialization for K = 2
    template<>
    KClass<2>::Data square();
};

template<>
KClass<2>::Data KClass<2>::square()
{
   Data result;
   result.data[0] = m_data.data[0] * m_data.data[0];
   result.data[1] = m_data.data[1] * m_data.data[1];
   return result;
}

int main()
{
   KClass<2> c;
   c.m_data.data[0] = c.m_data.data[1] = 1.f;
   c.square();
   
   return 0;
}

它有一个“KCalss”,它有一个模板数据成员(“m_data”)和一个对该数据成员(“square()”)执行一些计算的方法。例如,我想做的是针对 K = 2 的情况对“square()”进行专门化。

尝试使用 4.6.7 或 4.7.2 编译它会出现以下错误:

main.cpp:23:14: 错误:非命名空间范围'class KClass'中的显式特化

main.cpp:24:5:错误:'class KClass<2>'中的'Data'没有命名类型

知道我做错了什么吗?

提前致谢。

=== 编辑 ===

我发现的一种解决方法是将第二个“square()”方法也声明为模板:

template<int K2>
typename KClass<K2>::Data square();

它工作得很好,但它允许用户调用 'aquare()' 传递与类不同的模板参数,例如:

KClass<2> c;
c.square<3>;

这给出了“未定义的引用”链接错误。

=== 编辑(解决方案) ===

好吧,解决方案比我预期的要简单。我只需要删除模板声明:

template<>
inline KClass<2>::Data square();

,这是不必要的。

4

1 回答 1

1
template<>
KClass<2>::Data KClass<2>::square()
                ^^^^^^^^
{

你必须删除它。这不是您专门化成员函数的方式。成员函数不能在类范围内专门化。它需要在类声明的周围命名空间中专门化。

 template<>
 KClass<2>::Data square();
于 2013-05-02T13:56:46.240 回答