我从其他Stackoverflow线程(如this)中了解到,在编译时评估了Template参数。 此外,非类型模板参数应该是常量表达式,整数表达式或指向具有外部链接的对象的指针。
而且,我在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;
上面的代码在MS Visual Studio 2008上编译得很好。 在g ++上 - 我得到错误 - “转换为除了整数或枚举类型以外的类型不能出现在常量表达式中”
我在谷歌搜索后尝试了一些选项 -
声明“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 Object(null object pattern)方法的指针 见下文 -
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;
我仍然得到错误 - “ptr不能出现在常量表达式中”
所以现在我想知道 - 我应该传递什么价值才能让它发挥作用? 或者没有可能使它工作? (我的意思是一种不涉及使用c ++ 11标准的方法) 我没有-yet-找到一个将继续编译的值。
任何帮助表示赞赏(并且需要:-P)!
作为旁注,我还想问的另一件事是 - 是否有任何指针值可以用于非类型模板参数?
答案 0 :(得分:6)
C ++ 98表示非类型模板参数应为
之一
- 整数或枚举类型的整数常量表达式;或
- 非类型模板参数的名称;或
- 具有外部链接的对象或函数的名称,包括函数模板和函数 template-ids ,但不包括非静态类成员,表示为 id-expression ;或
- 具有外部链接的对象或函数的地址,包括函数模板和函数 template-ids ,但不包括非静态类成员,表示为&amp; id-expression &amp;如果名称引用函数或数组,则为option;或
- 指向成员的指针,如5.3.1所述。
空指针不属于此列表的任何项目,因此将空指针作为非类型模板参数传递无效。
C ++ 11将此列表更新为
- 表示整数或枚举类型的非类型模板参数, template-parameter 类型的转换常量表达式(5.19);或
- 非类型模板参数的名称;或
- 一个常量表达式(5.19),用于指定具有静态存储持续时间和外部或内部链接的对象的地址,或具有外部或内部链接的函数,包括函数模板和函数 template-ids 但排除非静态类成员,表示(忽略括号)为&amp; id-expression ,除了&amp;如果名称引用函数或数组,则可以省略,如果相应的 template-parameter 是引用,则应省略;或
- 一个求值为空指针值的常量表达式(4.10);或
- 一个常量表达式,其值为null成员指针值(4.11);或
- 指向成员的指针,如5.3.1所述。
更新的要求确实涵盖了空指针。因此,要将空指针用作非类型模板参数,必须使用C ++ 11。
答案 1 :(得分:0)
试试这个:
static const void* my_null_pointer = 0;
typedef A<void *, my_null_pointer, 1> ClassA;
这样的东西对我来说也适用于MSVC和gcc。 传递0作为模板参数也应该。
typedef A<void *, 0, 1> ClassA;