默认成员变量指针时的模板参数

时间:2015-06-29 10:01:12

标签: c++ templates

我需要一个模板类。我想传递一个类型的模板,然后传递两个成员变量指针。我希望第二个指针默认为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

3 个答案:

答案 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;
}

直播示例:https://ideone.com/2ICSBJ

答案 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