1

我从这个线程中知道 -模板类成员函数只专门化 ,如果我专门化一个类模板,我需要专门化所有成员函数。

所以,我的理由是我会“实例化”一个模板类。(不确定它是否正确的说法)

然后,由于这个实例化的类是一个成熟的类,我可以专门化一个特定的方法。

// I have a template class like this - 
template<class T, T invalidVal, int e> class A
{ 
     static inline bool dummy(T value) 
    {
        return 0;
    }
 }

 // Now I create classes from the above template class with 
 // T=void*, invalidVal=NULL & e=0 
 // And with T=void *, invalidVal=NULL & e=1 
 // And I typedef these classes to use them later
 typedef A<void *, (void *)NULL, 0> A_0;
 typedef A<void *, (void *)NULL, 1> A_1;

 // So now, what I was expecting was that A_0 & A_1 are classes and 
 // they can have their own specialized dummy() method
 // So I tried following - 
 inline bool A_0::dummy(void *value) 
 {
     return value != invalidVal;
 }

 inline bool A_1::dummy(void *value)
 {
     return value == invalidVal;
 }

上面的代码在 Windows 环境下工作。(视觉工作室 2008)

但是这种专业化在 Linux 上不起作用 - 使用 g++-4.7。通过阅读其他一些线程,我还将 -std=c++11 传递给我的 g++ 编译命令。

我收到以下 2 个错误 -

1. specializing member ‘A<void*, 0u, 0>::dummy’ requires ‘template<>’ syntax 
2. invalidVal was not declared in this scope

现在,错误号。template<>如果我在前面添加一个让我更担心的 1 消失inline bool A_0::dummy(void *value),因为我知道专业化并没有如我所愿地发生。

错误编号 2不会消失。

我对模板类成员函数专业化越来越感到困惑。我在这里错过了什么?g ++抱怨的任何原因?有任何想法吗?

谢谢!

4

1 回答 1

3

我不确定您所说的“专业化没有按我的意愿发生”是什么意思。你到底想要什么?

在您的代码中,您试图在不专门化类本身的情况下执行模板类成员的显式专门化。C++ 中所有形式的显式特化都需要template<>语法

template<>
inline bool A_0::dummy(void *value) 
{
  // Whatever
}

template<>
inline bool A_1::dummy(void *value)
{
  // Whatever
}

这就是它在 C++ 中的方式。仅仅因为你在 typedef-names 后面“隐藏”了专门的类名并不意味着你不必使用template<>语法。

template <>Visual C++ 显然允许您作为非标准扩展跳过部分。

此外,专用版本对模板参数名称一无所知(它们不再有任何参数),这意味着它们invalidVal完全不知道该名称。要么invalidVal用显式替换NULL(如在显式参数列表中),要么invalidVal通过类使值作为常量静态成员可用

template<class T, T invalidVal, int e> class A
{ 
  static const T iv; // declaration
  ...
};

template <class T, T invalidVal, int e>
const T A<T, invalidVal, e>::iv = invalidVal; // definition

template <> inline bool A_0::dummy(void *value) 
{
   return value != iv;
}
于 2012-08-09T18:43:07.453 回答