我从其他Stackoverflow线程(如此)中了解到模块参数在编译时进行评估.此外,非类型模板参数应该是常量表达式,整型表达式或指向具有外部链接的对象的指针.
而且,我在Makefile中的g ++命令中没有使用--std = c ++ 0x.
那么,是否可以实例化一个模板类,其中NULL作为参数传递?
// I have a template class like this -
template<class T, T invalidVal, int e> class A
{
static inline bool dummy(T value)
{
return 0;
}
}
#define MY_INVALID_VAL ((void *)0)
// Now I want create class from the above template class with
// T=void*, invalidVal=NULL & e=0
typedef A<void *, MY_INVALID_VAL, 1> ClassA;
Run Code Online (Sandbox Code Playgroud)
上面的代码在MS Visual Studio 2008上编译得很好.在g ++上 - 我得到错误 - "转换为除了整数或枚举类型以外的类型不能出现在常量表达式中"
我在google搜索后尝试了一些选项 -
声明"extern void*MY_INVALID_VAL;" 在头文件中 - 包含它并执行void MY_INVALID_VAL = NULL; 在模板实例化之前.在这种情况下,我得到错误"MY_INVALID_VAL不是类型'void ' 的有效模板参数,因为它不是一个常量指针"
所以我的问题是 - 在没有使用c ++ 0x标准的情况下,没有办法用NULL参数实例化模板类吗?
谢谢!
编辑:
感谢所有评论和感谢引用标准草案的确切部分.
只需列出我尝试过的东西 -
1)直接传递"0"不起作用.我得到的错误是 - "无法将'0'转换为模板参数void*"
2)声明static const void*my_null = 0; 并传递my_null不起作用.它给出了错误 - "my_null不能出现在常量表达式中"
3)尝试将指针指向null对象(null对象模式)方法中的一条评论建议见下文 -
class my_null
{
public:
my_null() { my_null_ptr = NULL; }
void * get() { return my_null_ptr; }
private:
void *my_null_ptr;
};
my_null my_null_obj;
my_null *ptr = &my_null_obj;
typedef A<void *, (void *)ptr, 1> ClassA;
Run Code Online (Sandbox Code Playgroud)
我仍然得到错误 - "ptr不能出现在常量表达式中"
所以现在我想知道 - 我应该通过什么价值才能让它发挥作用?或者没有可能使它工作?(我的意思是一种不涉及使用c ++ 11标准的方法)我没有-yet-找到一个将继续编译的值.
任何帮助表示赞赏(并且需要:-P)!
作为旁注,我想要问的另一件事是 - 是否有任何指针值可以用于非类型模板参数?
C++ 98说非类型模板参数应该是其中之一
- 积分或枚举类型的整数常量表达式 ; 要么
- 非类型模板参数的名称 ; 要么
- 具有外部链接的对象或函数的名称,包括函数模板和函数template-id,但不包括非静态类成员,表示为id-expression ; 要么
- 具有外部链接的对象或函数的地址,包括函数模板和函数template-id,但不包括非静态类成员,表示为&id-expression,其中&是选项,如果名称引用函数或数组; 要么
- 指向成员的指针,如5.3.1中所述.
空指针不属于此列表的任何项目,因此将空指针作为非类型模板参数传递无效.
C++ 11将此列表更新为
- 用于非类型模板参数整数或枚举类型,类型的转换后的常量表达式(5.19)的模板的参数 ; 要么
- 非类型模板参数的名称 ; 要么
- 一个常量表达式(5.19),用于指定具有静态存储持续时间和外部或内部链接的对象的地址,或具有外部或内部链接的函数,包括函数模板和函数模板-id,但不包括非静态类成员,表示(忽略)括号)as&id-expression,除非如果名称引用函数或数组,可以省略&,如果相应的template-parameter是引用,则省略; 要么
- 一个常量表达式,其值为空指针值(4.10); 要么
- 一个常量表达式,其值为null成员指针值(4.11); 要么
- 指向成员的指针,如5.3.1中所述.
更新的要求确实涵盖了空指针.因此,要将空指针用作非类型模板参数,必须使用C++ 11.