Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

return an immutable POD class from a function

Context

I'm working on a large project combined from different modules. We've got a exporter with a template function export<T>(const T& obj) which works only on POD types (it does static_assert for is_pod if you're curious). Currently I'm sitting on the part of the system that's responsible for cataloging some entities (their type is irrelevant) that are described by metadata. The metadata itself is returned by some function called metadata describe(const entity& obj), and should be immutable after returning. Of course the function itself sets the metadata members inside its body.

Problem

Due to the facts mentioned above, I need to design a const POD type. Since POD types cannot have user-defined constructors, the member variables themselves cannot be const. Also returning a const variable by value directly from describe is meaningless (or not very helpful to say the least).

Attemted solutions

So basically what I've thought of so far is:

  • overload exporter.export<T>(...) for metadata, but that's not really a solution since it solves only the problem with the current class, while in the final product there will be many types of entities (And I'm not talking about . Overloading the function for all the types seems just wrong.
  • design an immutable wrapper and return it from describe. That's what I'm currently doing, since I can't figure out a better way to solve the problem. The wrapper offers an implicit conversion to const &T and stores a T inside of itself, thus it can be passed directly to the export function.

Question

Is there a better way to return an immutable POD class from a function? Am I missing something? For simplicity reasons lets assume metadata is defined as follows:

struct metadata{
    int parameter1;
    time_t parameter2;
};

and describe works as follows (currently, skipping the current solution):

metadata describe(const entity& obj){
   metadata m;
   m.parameter1 = obj.param1();
   m.parameter2 = obj.param2();
   return m;
}
like image 624
Paweł Stawarz Avatar asked Jul 27 '14 23:07

Paweł Stawarz


1 Answers

You can make the member variables const, you just need to initialize the object with an initializer list:

struct metadata{
    const int parameter1;
    const time_t parameter2;
};

and

metadata describe(const entity& obj){
   return { obj.param1(), obj.param2() };
}
like image 199
Daniel Frey Avatar answered Nov 02 '22 03:11

Daniel Frey