0

The goal is to make kind of "smart getter" that gets the value from the current object if it is present, if not, it looks for the value in the parent object.

So this ValueGetter class contains pointer to the object it is contained in (gets it as run time parameter in constructor) and pointer to member it operates on as template parameter.

This is the most simple example:

template <class StyleType, int StyleType::*value>
struct ValueGetter
{
  ValueGetter(StyleType* containedIn);
  int get();
  // Looks if the value is present in this style,
  // if not it looks for the value in the parent style
};

struct Style
{
  Style *parent;
  int a;
  ValueGetter<Style, &Style::a> x; // Error: 'Style::a' : is not a type name, static, or enumerator
};

When I move the x outside of the scope of the class, it compiles. Generally it is possible for class to contain template dependent on the class type, so why this doesn't work? Is there any other way to solve this issue without storing the pointer to member in runtime in constructor? (So the structure would contain extra pointer for every value)

Edit: I just succesfully compiled it in GCC, but not in MSVC (2012), so is this MSVC compiler error?

kovarex
  • 1,766
  • 18
  • 34
  • 1
    What compiler are you using? – Andy Prowl May 20 '13 at 16:42
  • P.S.: Your snippet [compiles](http://ideone.com/R6xiba) on GCC 4.7.2 – Andy Prowl May 20 '13 at 16:43
  • Compiling in MSVC 2012. – kovarex May 20 '13 at 16:54
  • What is an `int StyleType::*` supposed to be anyway? – mwerschy May 20 '13 at 17:05
  • mwerschy: It is pointer to class member, something like offset in class, that can be used along the class pointer to get the value http://stackoverflow.com/questions/670734/c-pointer-to-class-data-member – kovarex May 20 '13 at 17:08
  • 1
    As noted, this appears to be a flaw in the amazing MSVC2012 C++11 compiler. :) What does it mean for `a` not to be present? Does `a` have to be a naked member of `Style`? Ie, `template struct Property { static_assert( std::is_base< Derived, Property >::value, "CRTP failure" ); T value; };`, with a `GetProperty(object)` access technique? – Yakk - Adam Nevraumont May 20 '13 at 17:15
  • Ah ok I wasn't aware that worked with things other than functions :) This only happens when declaring `x` in `Style` though... Moving it to main fixes the problem. Strange. – mwerschy May 20 '13 at 17:33

1 Answers1

1

I don't think pointers (not to confuse with pointer types as in T*) are allowed as template parameters in 03 C++, only type names, integral constants or enum constants. Not even float/double constants. That includes class member pointers.

Update: Also, static non-type parameters work:

template <class StyleType, int *value>
struct ValueGetter
{
  ValueGetter(StyleType* containedIn);
  int get();
  // Looks if the value is present in this style,
  // if not it looks for the value in the parent style
};

struct Style
{
  Style *parent;
  static int a;
  ValueGetter<Style, &Style::a> x; // Error: 'Style::a' : is not a type name, static, or enumerator
};
AlexK
  • 1,279
  • 8
  • 19