我需要一个模板类。我想传递一个类型的模板,然后传递两个成员变量指针。我希望第二个指针默认为NULL,因此是可选的。这是可能的,如果是这样,语法是什么?
我期望的语法是
template<typename T, int T::*VALUE1, int T::*VALUE2 = NULL>
class Foo { ... }
但是,当我尝试实例化此类的实例时;
Foo<Bar, &Bar::var1> fooBar;
虽然使用以下作品实例化
Foo<Bar, &Bar::var1, &Bar::var2> fooBar
给出的错误(来自g ++ 4.4)是
错误:无法将模板参数'0l'转换为'int Bar :: *'
请注意,我不能使用c ++ 11,因此无法使用nullptr
答案 0 :(得分:3)
从一开始,这种限制一直是语言。在C ++ 98中,不允许将0
用作指针类型或指向成员类型的任何模板参数的非类型模板参数。例如。这是无效的
template <int *p> struct S {};
...
S<0> s1; // ERROR: `0` is not a valid argument for `int *` parameter
S<(int *) 0> s2; // ERROR: unacceptable address expression
换句话说,在C ++语言的原始版本中,您根本不允许将空指针作为模板参数传递。它被语言作者故意阻止。这样做的机会只出现在C ++ 11中,引入了nullptr
。
答案 1 :(得分:2)
使用nullptr
:
struct Bar
{
int var1;
};
template<typename T, int T::*VALUE1, int T::*VALUE2 = nullptr>
struct Foo
{
};
int main()
{
Foo<Bar, &Bar::var1> fooBar;
return 0;
}
答案 2 :(得分:0)
正如here所解释的,指向类成员的指针用于提供对类成员的间接访问。现在对于对象的声明,foobar1需要一个类模板,它接受一个类bar的成员。
现在,您的第二个调用是完全不同的类模板,它希望访问类Bar的两个成员。
所以你必须为此目的定义两个不同的类模板,例如foo1和foo2,如下所示:
template<typename T, int T::*VALUE1>
class Foo1 { ... }
template<typename T, int T::*VALUE1, int T::*value2>
class Foo2 { ... }
你会这样称呼:
Foo1<Bar,&Bar::var1> foobar1;//use first class template Foo1
Foo2<Bar,&Bar::var1,&Bar::var2> foobar2;//use second class template Foo2