Question

I have the following classes in my project: Neuron, ActivationNeuron, Layer, and ActivationLayer as partly mentioned below.

class Neuron { }; /* abstract class */
class ActivationNeuron : public Neuron { };

class Layer {
protected:
    vector<shared_ptr<Neuron>> neurons;
public:
    Neuron& operator[](const int index) {
        return *this->neurons[index];
    }
};

class ActivationLayer : public Layer {
public:
    ActivationNeuron& operator[](const int index) {
        return *static_pointer_cast<ActivationNeuron>(this->neurons[index]);
    }
};

I have the following two questions:

  • Implementation/Syntax Related: Layer now uses shared_ptrs of Neurons. How should my implementation change if I plan to use unique_ptrs instead, given that static_pointer_cast is not available for unique_ptr ?

  • Semantics Related: Should I use unique_ptrs at all in this case, given that code in other classes (including my test cases) often invoke the indexing operator to call functions on the ActivationNeuron reference ?

  • More Semantics: The data is guaranteed to be used only as long as a Layer instance is in scope (no deferred logging). How is the decision of pointer type affected if I instead choose to return pointer<Neuron> and pointer<ActivationNeuron> instead of the references? I am more concerned about move/copy semantics and ownership policies rather than (non-drastic) effects in performance.

I also welcome improvements to my current implementation.

Was it helpful?

Solution

According to http://www.cplusplus.com/reference/memory/static_pointer_cast/ what you have is equivalent to

return *static_cast<ActivationNeuron*>(this->neurons[index].get());

The statement above will work for unique_ptr as well.

On the semantics side, you are changing the ownership model. Before anybody could hold on to the pointers. Now they will be bound to Layer. If all usage is while Layer exists it should be fine. If you need some components to access the data after Layer is destroyed (like deferred logging) then you will run into problems.

Not knowing the larger application is hard to say if there's any issue.

Performance wise: the static cast, indexing and the .get() are almost trivial (O(1) complexity, just memory indexing) and I wouldn't worry too much about their performance. You can do a profile to make sure that this is the case in your application. You are definitely only marginally worse as compared to vector<Neuron*>.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top