2

以下代码

#include <stdio.h>
template <typename T, T v> class Tem
{
    T t;
    Tem()
    {
        t = v;
    }
};

typedef Tem<FILE*,NULL> TemFile;

在 MacOS X 上由 Xcode 编译为 .mm 文件(Objective C++)时,会引发以下错误:

错误:无法将模板参数“0”转换为“文件*”。

请问这是怎么回事?有问题的代码在 MSVC 下编译得很好。从什么时候开始 0 常量不是指向任何东西的有效指针?这是Objective C++(而不是普通C++)的产物吗?

4

2 回答 2

1

按照标准,你运气不好。除了全局地址之外,没有办法将指针参数初始化为任何东西。§14.3.2/1:

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

  • 整数或枚举类型的整数常量表达式;或者
  • 非类型模板参数的名称;或者
  • 具有外部链接的对象或函数的地址,包括函数模板和函数模板 ID,但不包括非静态类成员,表示为 & id-expression 其中 & 是可选 的,如果名称指的是函数或数组,或者如果相应的模板参数是参考;或者
  • 指向成员的指针,如 5.3.1 中所述。

§14.3.2/5:

  • 对于指向对象的类型指针的非类型模板参数,应用限定转换(4.4)和数组到指针转换(4.2)。[注意:特别是,既不应用空指针转换(4.10),也不应用派生到基础的转换(4.10)。尽管 0 是整数类型的非类型模板参数的有效模板参数,但它不是指针类型的非类型模板参数的有效模板参数。]

但是,Comeau 接受这种无效的解决方法:

typedef Tem<FILE*, (FILE *) NULL > TemFile;

而且这段代码的合规性很小:我找不到标准在哪里明确指出使用默认表达式逐字替换缺少的参数,并且我找不到匹配的已知缺陷。有人有参考吗?

#include <stdio.h>
template <typename T, T *v = (T*) 0> class Tem
{
    T t;
    Tem()
    {
        t = v;
    }
};

typedef Tem<FILE> TemFile;

为了提高可移植性,您可能会考虑创建一个 bogus FILE FILE_NULL;、 pass&FILE_NULL和 test 指针相等性,而不是零。

于 2010-03-30T22:20:18.730 回答
-1

你尝试过这样的事情吗?

typedef Tem<FILE*,((FILE*)NULL)> TemFile;

也许它试图找出 NULL 的类型。

于 2010-03-30T21:51:32.323 回答