无法将模板参数NULL转换为void *

时间:2017-12-06 00:28:50

标签: c++ templates c++03

我已经提炼出一个让我感到困惑的问题,如下所示。基本上,gcc编译器不接受NULL作为void*类型的模板参数。

有解决方法吗?

请注意,我仅限于C ++ 03。

#define NULL 0

template<typename T = void , T* = NULL>
struct Foo
{
};

typedef Foo<> FooType;

int main()
{
}

修改:online version

1 个答案:

答案 0 :(得分:3)

您的问题没有解决方案:C ++ 03指针模板参数必须指定一个对象。使用NULL作为非类型模板参数是N1905中添加的一个功能,它在C ++ 03之后出现at least one year

  

14.3.2模板非类型参数

     

非类型非模板模板参数的模板参数应为以下之一:

     
      
  • 整数或枚举类型的整数常量表达式;或
  •   
  • 非类型模板参数的名称;或
  •   
  • 具有外部链接的对象或函数的地址,包括函数模板和函数template-id,但不包括非静态类成员,表示为&amp; id-expression其中&amp;如果名称引用函数或数组,或者相应的template-parameter是引用,则是可选的;或
  •   
  • (NEW)一个计算为空指针值的常量表达式(4.10);或
  •   
  • (NEW)一个常量表达式,其值为null成员指针值(4.11);或
  •   
  • 指向成员的指针,如5.3.1所述。
  •   

一个选项是声明一个“null struct”,其中包含一个可以使用的成员,而不是真正的NULL

template<typename T>
struct null
{
    static T value;
};

template<typename T, T* = &null<T>::value>
struct Foo
{
};

当然,访问null<T>::value具有明确定义的语义,并且不会崩溃;目的只是让一个地址保证与任何其他对象的地址不同。

请注意,在任何情况下,您都无法使用T = void。您无法使用null解决方法,因为void是不完整的类型;并且您不能将任何内容转换为void指针以用作非类型模板参数。