以下代码
#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'转换为'FILE *'。
发生了什么事,拜托?有问题的代码在MSVC下编译得很好。从什么时候0常量不是指向任何东西的有效指针?这是Objective C ++的工件(而不是vanilla C ++)吗?
答案 0 :(得分:1)
根据标准,你运气不好。除了全局地址之外,没有办法将指针参数初始化为任何东西。 §14.3.2/ 1:
非类型的模板参数, 非模板模板参数必须 是其中之一:
- 整数或枚举类型的整数常量表达式;或
- 非类型模板参数的名称;或
- 具有外部链接的对象或函数的地址,包括 功能模板和功能 template-ids但不包括非静态 班级成员,表示为&amp; id-expression其中&amp;是可选的 如果名称是指一个函数或 数组,或者如果相应的话 template-parameter是一个引用;或
- 指向成员的指针,如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;
为了获得更多的可移植性,您可以考虑创建一个伪FILE FILE_NULL;
,传递&FILE_NULL
,并测试指针与之相等而不是零。
答案 1 :(得分:-1)
你尝试过这样的事吗?
typedef Tem<FILE*,((FILE*)NULL)> TemFile;
也许它正试图找出NULL的类型。