Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I alias variables without incurring the storage cost of a reference?

Tags:

c++

alias

If I have the following code:

struct someStruct
{
  int x;
  int y;
}

class someClass
{
  public:
    someStruct m_member;

    alias      m_x = m_member.x; // I am aware alias is not a keyword and even if it was, I cannot assign it a value like this
    alias      m_y = m_member.y; // I am aware alias is not a keyword and even if it was, I cannot assign it a value like this
}

Can I give aliases to m_member.x and m_member.y without incurring the extra storage cost of a reference (which is the same as a pointer)? Something similar to a typedef?

like image 836
Samaursa Avatar asked Jan 12 '12 00:01

Samaursa


2 Answers

You can write inline access functions:

class someClass
{
public:
  someStruct m_member;
  int& mx() { return m_member.x; }
  int& my() { return m_member.y; }
  int const& mx() const { return m_member.x; }
  int const& my() const { return m_member.y; }
};

Then you can access the members as follows:

someClass foo;
foo.mx() = 3;
foo.my() = 2*foo.mx();

It's not exactly the same syntax, but close, and a reasonably good compiler will completely optimize away the inline functions.

like image 123
celtschk Avatar answered Oct 12 '22 23:10

celtschk


In this scenario I would just use a reference as it's what they're suited for. If a reference overhead is really too much I would just forgo the alias and use the full expression.

However you could achieve this with a macro (read: evil)

class someClass
{
  public:
    someStruct m_member;
#define m_x m_member.x
#define m_y m_member.y

  ...

#undef m_x
#undef m_y
};

I would highly recommend not doing this though. Like all macros though it has some unintended consequences (could cause incorrect referencing for other valid uses of m_x within the type).

For example

struct s1 {
  int m_x;
};

class someClass {
public:
  someStruct m_member;
#define m_x m_member.x
#define m_y m_member.y

  ...
  void Example(S1& s1) { 
    s1.m_x = 42;  // This wouldn't compile and you'd get terrible error messages
  }
};
like image 24
JaredPar Avatar answered Oct 12 '22 22:10

JaredPar