2

I have the need to have a template class. I want to pass the template a type and then two member variable pointers. The second pointer I want to be defaulted to NULL and thus optional. Is this possible and if so what is the syntax?

What I expected to be the syntax is

template<typename T, int T::*VALUE1, int T::*VALUE2 = NULL>
class Foo { ... }

However when I attempt to instantiate an instance of this class;

Foo<Bar, &Bar::var1> fooBar;

Though instantiating using the following works

Foo<Bar, &Bar::var1, &Bar::var2> fooBar

The error given (from g++ 4.4) is

error: could not convert template argument '0l' to 'int Bar::*'

Please note that I can not use c++11 and thus nullptr

lmcdowall
  • 423
  • 3
  • 11

3 Answers3

3

This restriction has been in the language since the beginning of times. In C++98 you are not allowed to use 0 as non-type template argument for any template parameters of pointer type or pointer-to-member type. E.g. this is invalid

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

In other words, in the original version of C++ language you were simply not allowed to pass null pointers as template parameters. It was deliberately blocked by the language authors. The opportunity to do so appeared only in C++11 with the introduction of nullptr.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
2

Use 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;
}

live example: https://ideone.com/2ICSBJ

m.s.
  • 16,063
  • 7
  • 53
  • 88
0

As explained here , pointer to class members are used to provide indirect access to class members. Now for the declaration of object foobar1 needs a class template that takes one member of class bar.

Now your second call is completely different class template which wants to access two members of class Bar.

So you will have to define two different class templates say foo1 and foo2 for that purpose as shown below :

  template<typename T, int T::*VALUE1>
  class Foo1 { ... }

  template<typename T, int T::*VALUE1, int T::*value2>
  class Foo2 { ... }

And you will call these like this :

  Foo1<Bar,&Bar::var1> foobar1;//use first class template Foo1
  Foo2<Bar,&Bar::var1,&Bar::var2> foobar2;//use second class template Foo2
Community
  • 1
  • 1
rahul tyagi
  • 643
  • 1
  • 7
  • 20
  • what kind of "functions" are you referring to? – m.s. Jun 29 '15 at 11:44
  • I have edited my answer i will get back to it when i will have access to a pc – rahul tyagi Jun 29 '15 at 11:46
  • Sorry but that doesn't answer my question and implementing the template class twice will be a maintenance issue. So whilst it might need to be done like that I was hoping there would be a syntax to write it. As others have mentioned this does exist in c++11 via the nullptr but I unfortunately can't use that – lmcdowall Jun 29 '15 at 15:23
  • 1
    I did some research and i dont think what you are trying to do can be achieved without c++11 – rahul tyagi Jun 29 '15 at 16:07