Reach C++ policy-based common interface with different template parameters from one container

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
0
down vote

favorite












Please review my solution for the following problem. I am interested in:



  • What do you think of the design

  • Improvement tips

  • Usability

  • Efficiency

Problem: Need to be store policy-based objects with different template parameters in one container, and reach the common interface.



Solution:
C++ Shell



#include <exception>
#include <iostream>
#include <memory>
#include <string>
#include <vector>

class SinglePolicy

public:
SinglePolicy() = default;

void push(int data)

std::cout << "set to SinglePolicyn";
buffer_ = data;


int pop()

std::cout << "return from SinglePolicyn";
int data = buffer_;

buffer_ = -1;

return data;


protected:
int buffer_;
;

class VectorPolicy

public:
VectorPolicy() = default;

virtual void push(int data)

std::cout << "emplace_back to VectorPolicyn";
buffer_.emplace_back(data);


virtual int pop()

std::cout << "pop front from VectorPolicyn";
if(buffer_.empty())
return -1;

int data = buffer_[0];
buffer_.erase(buffer_.begin());

return data;


protected:
std::vector<int> buffer_;
;

template<class BufferPolicy>
class PolicyBasedBuffer
: public BufferPolicy

public:
PolicyBasedBuffer()
: BufferPolicy()

;

typedef std::shared_ptr<PolicyBasedBuffer<SinglePolicy>> SinglePolicyPtr;
typedef std::shared_ptr<PolicyBasedBuffer<VectorPolicy>> VectorPolicyPtr;

class PolicyInterface

public:
PolicyInterface(const std::function<void(int)>& pushArg, const std::function<int(void)>& popArg)
: push(pushArg)
, pop(popArg)


const std::function<void(int)> push;
const std::function<int(void)> pop;
;

typedef std::shared_ptr<PolicyInterface> PolicyInterfacePtr;

PolicyInterfacePtr saveToPolicyInterface(const SinglePolicyPtr& aPolicy)

return std::make_shared<PolicyInterface>([aPolicy](int data) aPolicy->push(data); , [aPolicy]() return aPolicy->pop(); );


PolicyInterfacePtr saveToPolicyInterface(const VectorPolicyPtr& aPolicy)

return std::make_shared<PolicyInterface>([aPolicy](int data) aPolicy->push(data); , [aPolicy]() return aPolicy->pop(); );


int main()

auto singleBuffer = std::make_shared<PolicyBasedBuffer<SinglePolicy>>();
auto vectorBuffer = std::make_shared<PolicyBasedBuffer<VectorPolicy>>();

const int seven = 7;

std::cout << "PolicyBasedBuffer test:n";
singleBuffer->push(seven);
if(seven != singleBuffer->pop())
throw std::runtime_error("SinglePolicy :: wrong return data");

vectorBuffer->push(seven);
if(seven != vectorBuffer->pop())
throw std::runtime_error("VectorPolicy :: wrong return data");

std::vector<PolicyInterfacePtr> policy;

policy.push_back(saveToPolicyInterface(std::make_shared<PolicyBasedBuffer<SinglePolicy>>()));
policy.push_back(saveToPolicyInterface(std::make_shared<PolicyBasedBuffer<VectorPolicy>>()));

std::cout << "nPolicyInterface test:n";

for(size_t i=0; i < policy.size(); ++i)

policy[i]->push(seven);
if(seven != policy[i]->pop())
throw std::runtime_error("policyInterface :: wrong return data");


std::cout << std::flush;







share|improve this question



























    up vote
    0
    down vote

    favorite












    Please review my solution for the following problem. I am interested in:



    • What do you think of the design

    • Improvement tips

    • Usability

    • Efficiency

    Problem: Need to be store policy-based objects with different template parameters in one container, and reach the common interface.



    Solution:
    C++ Shell



    #include <exception>
    #include <iostream>
    #include <memory>
    #include <string>
    #include <vector>

    class SinglePolicy

    public:
    SinglePolicy() = default;

    void push(int data)

    std::cout << "set to SinglePolicyn";
    buffer_ = data;


    int pop()

    std::cout << "return from SinglePolicyn";
    int data = buffer_;

    buffer_ = -1;

    return data;


    protected:
    int buffer_;
    ;

    class VectorPolicy

    public:
    VectorPolicy() = default;

    virtual void push(int data)

    std::cout << "emplace_back to VectorPolicyn";
    buffer_.emplace_back(data);


    virtual int pop()

    std::cout << "pop front from VectorPolicyn";
    if(buffer_.empty())
    return -1;

    int data = buffer_[0];
    buffer_.erase(buffer_.begin());

    return data;


    protected:
    std::vector<int> buffer_;
    ;

    template<class BufferPolicy>
    class PolicyBasedBuffer
    : public BufferPolicy

    public:
    PolicyBasedBuffer()
    : BufferPolicy()

    ;

    typedef std::shared_ptr<PolicyBasedBuffer<SinglePolicy>> SinglePolicyPtr;
    typedef std::shared_ptr<PolicyBasedBuffer<VectorPolicy>> VectorPolicyPtr;

    class PolicyInterface

    public:
    PolicyInterface(const std::function<void(int)>& pushArg, const std::function<int(void)>& popArg)
    : push(pushArg)
    , pop(popArg)


    const std::function<void(int)> push;
    const std::function<int(void)> pop;
    ;

    typedef std::shared_ptr<PolicyInterface> PolicyInterfacePtr;

    PolicyInterfacePtr saveToPolicyInterface(const SinglePolicyPtr& aPolicy)

    return std::make_shared<PolicyInterface>([aPolicy](int data) aPolicy->push(data); , [aPolicy]() return aPolicy->pop(); );


    PolicyInterfacePtr saveToPolicyInterface(const VectorPolicyPtr& aPolicy)

    return std::make_shared<PolicyInterface>([aPolicy](int data) aPolicy->push(data); , [aPolicy]() return aPolicy->pop(); );


    int main()

    auto singleBuffer = std::make_shared<PolicyBasedBuffer<SinglePolicy>>();
    auto vectorBuffer = std::make_shared<PolicyBasedBuffer<VectorPolicy>>();

    const int seven = 7;

    std::cout << "PolicyBasedBuffer test:n";
    singleBuffer->push(seven);
    if(seven != singleBuffer->pop())
    throw std::runtime_error("SinglePolicy :: wrong return data");

    vectorBuffer->push(seven);
    if(seven != vectorBuffer->pop())
    throw std::runtime_error("VectorPolicy :: wrong return data");

    std::vector<PolicyInterfacePtr> policy;

    policy.push_back(saveToPolicyInterface(std::make_shared<PolicyBasedBuffer<SinglePolicy>>()));
    policy.push_back(saveToPolicyInterface(std::make_shared<PolicyBasedBuffer<VectorPolicy>>()));

    std::cout << "nPolicyInterface test:n";

    for(size_t i=0; i < policy.size(); ++i)

    policy[i]->push(seven);
    if(seven != policy[i]->pop())
    throw std::runtime_error("policyInterface :: wrong return data");


    std::cout << std::flush;







    share|improve this question























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      Please review my solution for the following problem. I am interested in:



      • What do you think of the design

      • Improvement tips

      • Usability

      • Efficiency

      Problem: Need to be store policy-based objects with different template parameters in one container, and reach the common interface.



      Solution:
      C++ Shell



      #include <exception>
      #include <iostream>
      #include <memory>
      #include <string>
      #include <vector>

      class SinglePolicy

      public:
      SinglePolicy() = default;

      void push(int data)

      std::cout << "set to SinglePolicyn";
      buffer_ = data;


      int pop()

      std::cout << "return from SinglePolicyn";
      int data = buffer_;

      buffer_ = -1;

      return data;


      protected:
      int buffer_;
      ;

      class VectorPolicy

      public:
      VectorPolicy() = default;

      virtual void push(int data)

      std::cout << "emplace_back to VectorPolicyn";
      buffer_.emplace_back(data);


      virtual int pop()

      std::cout << "pop front from VectorPolicyn";
      if(buffer_.empty())
      return -1;

      int data = buffer_[0];
      buffer_.erase(buffer_.begin());

      return data;


      protected:
      std::vector<int> buffer_;
      ;

      template<class BufferPolicy>
      class PolicyBasedBuffer
      : public BufferPolicy

      public:
      PolicyBasedBuffer()
      : BufferPolicy()

      ;

      typedef std::shared_ptr<PolicyBasedBuffer<SinglePolicy>> SinglePolicyPtr;
      typedef std::shared_ptr<PolicyBasedBuffer<VectorPolicy>> VectorPolicyPtr;

      class PolicyInterface

      public:
      PolicyInterface(const std::function<void(int)>& pushArg, const std::function<int(void)>& popArg)
      : push(pushArg)
      , pop(popArg)


      const std::function<void(int)> push;
      const std::function<int(void)> pop;
      ;

      typedef std::shared_ptr<PolicyInterface> PolicyInterfacePtr;

      PolicyInterfacePtr saveToPolicyInterface(const SinglePolicyPtr& aPolicy)

      return std::make_shared<PolicyInterface>([aPolicy](int data) aPolicy->push(data); , [aPolicy]() return aPolicy->pop(); );


      PolicyInterfacePtr saveToPolicyInterface(const VectorPolicyPtr& aPolicy)

      return std::make_shared<PolicyInterface>([aPolicy](int data) aPolicy->push(data); , [aPolicy]() return aPolicy->pop(); );


      int main()

      auto singleBuffer = std::make_shared<PolicyBasedBuffer<SinglePolicy>>();
      auto vectorBuffer = std::make_shared<PolicyBasedBuffer<VectorPolicy>>();

      const int seven = 7;

      std::cout << "PolicyBasedBuffer test:n";
      singleBuffer->push(seven);
      if(seven != singleBuffer->pop())
      throw std::runtime_error("SinglePolicy :: wrong return data");

      vectorBuffer->push(seven);
      if(seven != vectorBuffer->pop())
      throw std::runtime_error("VectorPolicy :: wrong return data");

      std::vector<PolicyInterfacePtr> policy;

      policy.push_back(saveToPolicyInterface(std::make_shared<PolicyBasedBuffer<SinglePolicy>>()));
      policy.push_back(saveToPolicyInterface(std::make_shared<PolicyBasedBuffer<VectorPolicy>>()));

      std::cout << "nPolicyInterface test:n";

      for(size_t i=0; i < policy.size(); ++i)

      policy[i]->push(seven);
      if(seven != policy[i]->pop())
      throw std::runtime_error("policyInterface :: wrong return data");


      std::cout << std::flush;







      share|improve this question













      Please review my solution for the following problem. I am interested in:



      • What do you think of the design

      • Improvement tips

      • Usability

      • Efficiency

      Problem: Need to be store policy-based objects with different template parameters in one container, and reach the common interface.



      Solution:
      C++ Shell



      #include <exception>
      #include <iostream>
      #include <memory>
      #include <string>
      #include <vector>

      class SinglePolicy

      public:
      SinglePolicy() = default;

      void push(int data)

      std::cout << "set to SinglePolicyn";
      buffer_ = data;


      int pop()

      std::cout << "return from SinglePolicyn";
      int data = buffer_;

      buffer_ = -1;

      return data;


      protected:
      int buffer_;
      ;

      class VectorPolicy

      public:
      VectorPolicy() = default;

      virtual void push(int data)

      std::cout << "emplace_back to VectorPolicyn";
      buffer_.emplace_back(data);


      virtual int pop()

      std::cout << "pop front from VectorPolicyn";
      if(buffer_.empty())
      return -1;

      int data = buffer_[0];
      buffer_.erase(buffer_.begin());

      return data;


      protected:
      std::vector<int> buffer_;
      ;

      template<class BufferPolicy>
      class PolicyBasedBuffer
      : public BufferPolicy

      public:
      PolicyBasedBuffer()
      : BufferPolicy()

      ;

      typedef std::shared_ptr<PolicyBasedBuffer<SinglePolicy>> SinglePolicyPtr;
      typedef std::shared_ptr<PolicyBasedBuffer<VectorPolicy>> VectorPolicyPtr;

      class PolicyInterface

      public:
      PolicyInterface(const std::function<void(int)>& pushArg, const std::function<int(void)>& popArg)
      : push(pushArg)
      , pop(popArg)


      const std::function<void(int)> push;
      const std::function<int(void)> pop;
      ;

      typedef std::shared_ptr<PolicyInterface> PolicyInterfacePtr;

      PolicyInterfacePtr saveToPolicyInterface(const SinglePolicyPtr& aPolicy)

      return std::make_shared<PolicyInterface>([aPolicy](int data) aPolicy->push(data); , [aPolicy]() return aPolicy->pop(); );


      PolicyInterfacePtr saveToPolicyInterface(const VectorPolicyPtr& aPolicy)

      return std::make_shared<PolicyInterface>([aPolicy](int data) aPolicy->push(data); , [aPolicy]() return aPolicy->pop(); );


      int main()

      auto singleBuffer = std::make_shared<PolicyBasedBuffer<SinglePolicy>>();
      auto vectorBuffer = std::make_shared<PolicyBasedBuffer<VectorPolicy>>();

      const int seven = 7;

      std::cout << "PolicyBasedBuffer test:n";
      singleBuffer->push(seven);
      if(seven != singleBuffer->pop())
      throw std::runtime_error("SinglePolicy :: wrong return data");

      vectorBuffer->push(seven);
      if(seven != vectorBuffer->pop())
      throw std::runtime_error("VectorPolicy :: wrong return data");

      std::vector<PolicyInterfacePtr> policy;

      policy.push_back(saveToPolicyInterface(std::make_shared<PolicyBasedBuffer<SinglePolicy>>()));
      policy.push_back(saveToPolicyInterface(std::make_shared<PolicyBasedBuffer<VectorPolicy>>()));

      std::cout << "nPolicyInterface test:n";

      for(size_t i=0; i < policy.size(); ++i)

      policy[i]->push(seven);
      if(seven != policy[i]->pop())
      throw std::runtime_error("policyInterface :: wrong return data");


      std::cout << std::flush;









      share|improve this question












      share|improve this question




      share|improve this question








      edited Apr 4 at 14:05
























      asked Apr 3 at 22:38









      István Simon

      1234




      1234




















          2 Answers
          2






          active

          oldest

          votes

















          up vote
          4
          down vote



          accepted










          Few minor notes.



          1. You have deliberately assigned -1 to represent undef, correct? The question whether you'll ever need to store -1 aside, you should probably define a named constant to get rid of magic number (it also helps when you decide to accept -1s). BTW, the minimal int (-2³¹ or so) is maybe a better alternative.


          2. Every constructor and factory function accepts arguments by const ref. While acceptable for shared_ptr args, it makes sense to accept others (such as closures) by value and then move them inside the object's members.


          3. const_cast is a threat to PolicyInterface's public push and pop methods.


          4. VectorPolicy pushes elements to its right end but pops them on the left. If it should work as a LILO queue, std::deque is a better alternative to std::vector. Otherwise, VectorPolicy should follow stack (LIFO) idiom, and elements popped at the end.






          share|improve this answer























          • "Need to be store policy-based objects with different template parameters in one container." That means the VectorPolicy and SinglePolicy and the PolicyBasedBuffer only example for usage.
            – István Simon
            Apr 4 at 0:54











          • const_cast from what to what? What are you mean for threat to?
            – István Simon
            Apr 4 at 0:56






          • 1




            One can write something like const_cast<std::function<void(int)> &>(buffer.push) = (int) std::cout << "Ignored an int" << std::endl; ; and the object is no more consistent or safe,
            – bipll
            Apr 4 at 0:59










          • Yes in this way anybody can overwrite the value. Thanks.
            – István Simon
            Apr 4 at 1:06










          • @IstvánSimon I have rolled back Rev 3 → 2. Please see What to do when someone answers.
            – 200_success
            Apr 4 at 1:39

















          up vote
          2
          down vote













          I’m having trouble following this code.



          You have classes SinglePolicy and VectorPolicy that look like they should be polymorphic versions of an abstract policy because they have the same push and pop functions which are declared virtual. But they are not derived from anything.



          Then, you have a template PolicyBasedBuffer which as far as I can tell doesn’t do anything at all. It derives from one of the above classes, but then adds no functionality or members at all. So why?



          Then you have PolyInterface which holds pointers to push and pop functions, with free functions to populate with the push/pop from the original Policy classes.



          That’s what the base class would have done automatically.



          I think what you want is:



          class PolicyInterface 
          public:
          virtual void push(int data) = 0;
          virtual int pop() = 0;
          ;

          class VectorPolicy : public PolicyInterface {
          public:
          void push(int data) override

          // ⋯ your implementation here

          ⋮


          and likewise for the ScalarPolicy — derive it from PolicyInterface.



          Now, you can have:



          std::vector<unique_ptr<PolicyInterface>> policies;
          policies.push_back(make_shared<VectorPolicy>());
          policies.push_back(make_shared<ScalarPolicy>());
          ⋮
          policies[i]->push(seven);



          You mentioned policy-based objects with different template parameters in your problem statement. I don’t see any need for a template at all here, but perhaps the concrete example code simply doesn’t show the need?



          The overall idea here is still the right thing. The derived class can be a template, which inherits from the interface. Stated like that, it sounds a lot like what your original code did! But you were deriving a meaningless class from the needed class, not deriving the needed class (which might happen to be templated) from an interface. Since you had virtual functions in the policy classes, I think you were confused and this is what you were trying to do.



          template <typename T, size_t N>
          class FlexPolicy : PolicyInterface
          ⋮
          ;

          policies.push_back( make_unique<FlexPolicy<string,5>> );



          Misc tip: use the std::stack container adaptor instead of a plain vector.



          I like your use of the C++shell web site for holding the code. Too bad it doesn’t have C++17 ☹.






          share|improve this answer





















          • I get it, I didn't take enough time to the example for present correctly the problem. I will create a new question a much better example. PolicyInterface's concept would be the subject of the question where store function pointers in the class. bipll pointed to a mistake.
            – István Simon
            Apr 5 at 7:14











          • std::stack is a FILO solution, but I use hear a FIFO solution. Maybe the std::deque can be better than std::vector, but with small element size the std::vector is faster.
            – István Simon
            Apr 5 at 7:28







          • 1




            You are right, your solution is much better for what the example try to present.
            – István Simon
            Apr 5 at 7:33










          Your Answer




          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f191207%2freach-c-policy-based-common-interface-with-different-template-parameters-from%23new-answer', 'question_page');

          );

          Post as a guest






























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          4
          down vote



          accepted










          Few minor notes.



          1. You have deliberately assigned -1 to represent undef, correct? The question whether you'll ever need to store -1 aside, you should probably define a named constant to get rid of magic number (it also helps when you decide to accept -1s). BTW, the minimal int (-2³¹ or so) is maybe a better alternative.


          2. Every constructor and factory function accepts arguments by const ref. While acceptable for shared_ptr args, it makes sense to accept others (such as closures) by value and then move them inside the object's members.


          3. const_cast is a threat to PolicyInterface's public push and pop methods.


          4. VectorPolicy pushes elements to its right end but pops them on the left. If it should work as a LILO queue, std::deque is a better alternative to std::vector. Otherwise, VectorPolicy should follow stack (LIFO) idiom, and elements popped at the end.






          share|improve this answer























          • "Need to be store policy-based objects with different template parameters in one container." That means the VectorPolicy and SinglePolicy and the PolicyBasedBuffer only example for usage.
            – István Simon
            Apr 4 at 0:54











          • const_cast from what to what? What are you mean for threat to?
            – István Simon
            Apr 4 at 0:56






          • 1




            One can write something like const_cast<std::function<void(int)> &>(buffer.push) = (int) std::cout << "Ignored an int" << std::endl; ; and the object is no more consistent or safe,
            – bipll
            Apr 4 at 0:59










          • Yes in this way anybody can overwrite the value. Thanks.
            – István Simon
            Apr 4 at 1:06










          • @IstvánSimon I have rolled back Rev 3 → 2. Please see What to do when someone answers.
            – 200_success
            Apr 4 at 1:39














          up vote
          4
          down vote



          accepted










          Few minor notes.



          1. You have deliberately assigned -1 to represent undef, correct? The question whether you'll ever need to store -1 aside, you should probably define a named constant to get rid of magic number (it also helps when you decide to accept -1s). BTW, the minimal int (-2³¹ or so) is maybe a better alternative.


          2. Every constructor and factory function accepts arguments by const ref. While acceptable for shared_ptr args, it makes sense to accept others (such as closures) by value and then move them inside the object's members.


          3. const_cast is a threat to PolicyInterface's public push and pop methods.


          4. VectorPolicy pushes elements to its right end but pops them on the left. If it should work as a LILO queue, std::deque is a better alternative to std::vector. Otherwise, VectorPolicy should follow stack (LIFO) idiom, and elements popped at the end.






          share|improve this answer























          • "Need to be store policy-based objects with different template parameters in one container." That means the VectorPolicy and SinglePolicy and the PolicyBasedBuffer only example for usage.
            – István Simon
            Apr 4 at 0:54











          • const_cast from what to what? What are you mean for threat to?
            – István Simon
            Apr 4 at 0:56






          • 1




            One can write something like const_cast<std::function<void(int)> &>(buffer.push) = (int) std::cout << "Ignored an int" << std::endl; ; and the object is no more consistent or safe,
            – bipll
            Apr 4 at 0:59










          • Yes in this way anybody can overwrite the value. Thanks.
            – István Simon
            Apr 4 at 1:06










          • @IstvánSimon I have rolled back Rev 3 → 2. Please see What to do when someone answers.
            – 200_success
            Apr 4 at 1:39












          up vote
          4
          down vote



          accepted







          up vote
          4
          down vote



          accepted






          Few minor notes.



          1. You have deliberately assigned -1 to represent undef, correct? The question whether you'll ever need to store -1 aside, you should probably define a named constant to get rid of magic number (it also helps when you decide to accept -1s). BTW, the minimal int (-2³¹ or so) is maybe a better alternative.


          2. Every constructor and factory function accepts arguments by const ref. While acceptable for shared_ptr args, it makes sense to accept others (such as closures) by value and then move them inside the object's members.


          3. const_cast is a threat to PolicyInterface's public push and pop methods.


          4. VectorPolicy pushes elements to its right end but pops them on the left. If it should work as a LILO queue, std::deque is a better alternative to std::vector. Otherwise, VectorPolicy should follow stack (LIFO) idiom, and elements popped at the end.






          share|improve this answer















          Few minor notes.



          1. You have deliberately assigned -1 to represent undef, correct? The question whether you'll ever need to store -1 aside, you should probably define a named constant to get rid of magic number (it also helps when you decide to accept -1s). BTW, the minimal int (-2³¹ or so) is maybe a better alternative.


          2. Every constructor and factory function accepts arguments by const ref. While acceptable for shared_ptr args, it makes sense to accept others (such as closures) by value and then move them inside the object's members.


          3. const_cast is a threat to PolicyInterface's public push and pop methods.


          4. VectorPolicy pushes elements to its right end but pops them on the left. If it should work as a LILO queue, std::deque is a better alternative to std::vector. Otherwise, VectorPolicy should follow stack (LIFO) idiom, and elements popped at the end.







          share|improve this answer















          share|improve this answer



          share|improve this answer








          edited Apr 6 at 11:13


























          answered Apr 4 at 0:35









          bipll

          4026




          4026











          • "Need to be store policy-based objects with different template parameters in one container." That means the VectorPolicy and SinglePolicy and the PolicyBasedBuffer only example for usage.
            – István Simon
            Apr 4 at 0:54











          • const_cast from what to what? What are you mean for threat to?
            – István Simon
            Apr 4 at 0:56






          • 1




            One can write something like const_cast<std::function<void(int)> &>(buffer.push) = (int) std::cout << "Ignored an int" << std::endl; ; and the object is no more consistent or safe,
            – bipll
            Apr 4 at 0:59










          • Yes in this way anybody can overwrite the value. Thanks.
            – István Simon
            Apr 4 at 1:06










          • @IstvánSimon I have rolled back Rev 3 → 2. Please see What to do when someone answers.
            – 200_success
            Apr 4 at 1:39
















          • "Need to be store policy-based objects with different template parameters in one container." That means the VectorPolicy and SinglePolicy and the PolicyBasedBuffer only example for usage.
            – István Simon
            Apr 4 at 0:54











          • const_cast from what to what? What are you mean for threat to?
            – István Simon
            Apr 4 at 0:56






          • 1




            One can write something like const_cast<std::function<void(int)> &>(buffer.push) = (int) std::cout << "Ignored an int" << std::endl; ; and the object is no more consistent or safe,
            – bipll
            Apr 4 at 0:59










          • Yes in this way anybody can overwrite the value. Thanks.
            – István Simon
            Apr 4 at 1:06










          • @IstvánSimon I have rolled back Rev 3 → 2. Please see What to do when someone answers.
            – 200_success
            Apr 4 at 1:39















          "Need to be store policy-based objects with different template parameters in one container." That means the VectorPolicy and SinglePolicy and the PolicyBasedBuffer only example for usage.
          – István Simon
          Apr 4 at 0:54





          "Need to be store policy-based objects with different template parameters in one container." That means the VectorPolicy and SinglePolicy and the PolicyBasedBuffer only example for usage.
          – István Simon
          Apr 4 at 0:54













          const_cast from what to what? What are you mean for threat to?
          – István Simon
          Apr 4 at 0:56




          const_cast from what to what? What are you mean for threat to?
          – István Simon
          Apr 4 at 0:56




          1




          1




          One can write something like const_cast<std::function<void(int)> &>(buffer.push) = (int) std::cout << "Ignored an int" << std::endl; ; and the object is no more consistent or safe,
          – bipll
          Apr 4 at 0:59




          One can write something like const_cast<std::function<void(int)> &>(buffer.push) = (int) std::cout << "Ignored an int" << std::endl; ; and the object is no more consistent or safe,
          – bipll
          Apr 4 at 0:59












          Yes in this way anybody can overwrite the value. Thanks.
          – István Simon
          Apr 4 at 1:06




          Yes in this way anybody can overwrite the value. Thanks.
          – István Simon
          Apr 4 at 1:06












          @IstvánSimon I have rolled back Rev 3 → 2. Please see What to do when someone answers.
          – 200_success
          Apr 4 at 1:39




          @IstvánSimon I have rolled back Rev 3 → 2. Please see What to do when someone answers.
          – 200_success
          Apr 4 at 1:39












          up vote
          2
          down vote













          I’m having trouble following this code.



          You have classes SinglePolicy and VectorPolicy that look like they should be polymorphic versions of an abstract policy because they have the same push and pop functions which are declared virtual. But they are not derived from anything.



          Then, you have a template PolicyBasedBuffer which as far as I can tell doesn’t do anything at all. It derives from one of the above classes, but then adds no functionality or members at all. So why?



          Then you have PolyInterface which holds pointers to push and pop functions, with free functions to populate with the push/pop from the original Policy classes.



          That’s what the base class would have done automatically.



          I think what you want is:



          class PolicyInterface 
          public:
          virtual void push(int data) = 0;
          virtual int pop() = 0;
          ;

          class VectorPolicy : public PolicyInterface {
          public:
          void push(int data) override

          // ⋯ your implementation here

          ⋮


          and likewise for the ScalarPolicy — derive it from PolicyInterface.



          Now, you can have:



          std::vector<unique_ptr<PolicyInterface>> policies;
          policies.push_back(make_shared<VectorPolicy>());
          policies.push_back(make_shared<ScalarPolicy>());
          ⋮
          policies[i]->push(seven);



          You mentioned policy-based objects with different template parameters in your problem statement. I don’t see any need for a template at all here, but perhaps the concrete example code simply doesn’t show the need?



          The overall idea here is still the right thing. The derived class can be a template, which inherits from the interface. Stated like that, it sounds a lot like what your original code did! But you were deriving a meaningless class from the needed class, not deriving the needed class (which might happen to be templated) from an interface. Since you had virtual functions in the policy classes, I think you were confused and this is what you were trying to do.



          template <typename T, size_t N>
          class FlexPolicy : PolicyInterface
          ⋮
          ;

          policies.push_back( make_unique<FlexPolicy<string,5>> );



          Misc tip: use the std::stack container adaptor instead of a plain vector.



          I like your use of the C++shell web site for holding the code. Too bad it doesn’t have C++17 ☹.






          share|improve this answer





















          • I get it, I didn't take enough time to the example for present correctly the problem. I will create a new question a much better example. PolicyInterface's concept would be the subject of the question where store function pointers in the class. bipll pointed to a mistake.
            – István Simon
            Apr 5 at 7:14











          • std::stack is a FILO solution, but I use hear a FIFO solution. Maybe the std::deque can be better than std::vector, but with small element size the std::vector is faster.
            – István Simon
            Apr 5 at 7:28







          • 1




            You are right, your solution is much better for what the example try to present.
            – István Simon
            Apr 5 at 7:33














          up vote
          2
          down vote













          I’m having trouble following this code.



          You have classes SinglePolicy and VectorPolicy that look like they should be polymorphic versions of an abstract policy because they have the same push and pop functions which are declared virtual. But they are not derived from anything.



          Then, you have a template PolicyBasedBuffer which as far as I can tell doesn’t do anything at all. It derives from one of the above classes, but then adds no functionality or members at all. So why?



          Then you have PolyInterface which holds pointers to push and pop functions, with free functions to populate with the push/pop from the original Policy classes.



          That’s what the base class would have done automatically.



          I think what you want is:



          class PolicyInterface 
          public:
          virtual void push(int data) = 0;
          virtual int pop() = 0;
          ;

          class VectorPolicy : public PolicyInterface {
          public:
          void push(int data) override

          // ⋯ your implementation here

          ⋮


          and likewise for the ScalarPolicy — derive it from PolicyInterface.



          Now, you can have:



          std::vector<unique_ptr<PolicyInterface>> policies;
          policies.push_back(make_shared<VectorPolicy>());
          policies.push_back(make_shared<ScalarPolicy>());
          ⋮
          policies[i]->push(seven);



          You mentioned policy-based objects with different template parameters in your problem statement. I don’t see any need for a template at all here, but perhaps the concrete example code simply doesn’t show the need?



          The overall idea here is still the right thing. The derived class can be a template, which inherits from the interface. Stated like that, it sounds a lot like what your original code did! But you were deriving a meaningless class from the needed class, not deriving the needed class (which might happen to be templated) from an interface. Since you had virtual functions in the policy classes, I think you were confused and this is what you were trying to do.



          template <typename T, size_t N>
          class FlexPolicy : PolicyInterface
          ⋮
          ;

          policies.push_back( make_unique<FlexPolicy<string,5>> );



          Misc tip: use the std::stack container adaptor instead of a plain vector.



          I like your use of the C++shell web site for holding the code. Too bad it doesn’t have C++17 ☹.






          share|improve this answer





















          • I get it, I didn't take enough time to the example for present correctly the problem. I will create a new question a much better example. PolicyInterface's concept would be the subject of the question where store function pointers in the class. bipll pointed to a mistake.
            – István Simon
            Apr 5 at 7:14











          • std::stack is a FILO solution, but I use hear a FIFO solution. Maybe the std::deque can be better than std::vector, but with small element size the std::vector is faster.
            – István Simon
            Apr 5 at 7:28







          • 1




            You are right, your solution is much better for what the example try to present.
            – István Simon
            Apr 5 at 7:33












          up vote
          2
          down vote










          up vote
          2
          down vote









          I’m having trouble following this code.



          You have classes SinglePolicy and VectorPolicy that look like they should be polymorphic versions of an abstract policy because they have the same push and pop functions which are declared virtual. But they are not derived from anything.



          Then, you have a template PolicyBasedBuffer which as far as I can tell doesn’t do anything at all. It derives from one of the above classes, but then adds no functionality or members at all. So why?



          Then you have PolyInterface which holds pointers to push and pop functions, with free functions to populate with the push/pop from the original Policy classes.



          That’s what the base class would have done automatically.



          I think what you want is:



          class PolicyInterface 
          public:
          virtual void push(int data) = 0;
          virtual int pop() = 0;
          ;

          class VectorPolicy : public PolicyInterface {
          public:
          void push(int data) override

          // ⋯ your implementation here

          ⋮


          and likewise for the ScalarPolicy — derive it from PolicyInterface.



          Now, you can have:



          std::vector<unique_ptr<PolicyInterface>> policies;
          policies.push_back(make_shared<VectorPolicy>());
          policies.push_back(make_shared<ScalarPolicy>());
          ⋮
          policies[i]->push(seven);



          You mentioned policy-based objects with different template parameters in your problem statement. I don’t see any need for a template at all here, but perhaps the concrete example code simply doesn’t show the need?



          The overall idea here is still the right thing. The derived class can be a template, which inherits from the interface. Stated like that, it sounds a lot like what your original code did! But you were deriving a meaningless class from the needed class, not deriving the needed class (which might happen to be templated) from an interface. Since you had virtual functions in the policy classes, I think you were confused and this is what you were trying to do.



          template <typename T, size_t N>
          class FlexPolicy : PolicyInterface
          ⋮
          ;

          policies.push_back( make_unique<FlexPolicy<string,5>> );



          Misc tip: use the std::stack container adaptor instead of a plain vector.



          I like your use of the C++shell web site for holding the code. Too bad it doesn’t have C++17 ☹.






          share|improve this answer













          I’m having trouble following this code.



          You have classes SinglePolicy and VectorPolicy that look like they should be polymorphic versions of an abstract policy because they have the same push and pop functions which are declared virtual. But they are not derived from anything.



          Then, you have a template PolicyBasedBuffer which as far as I can tell doesn’t do anything at all. It derives from one of the above classes, but then adds no functionality or members at all. So why?



          Then you have PolyInterface which holds pointers to push and pop functions, with free functions to populate with the push/pop from the original Policy classes.



          That’s what the base class would have done automatically.



          I think what you want is:



          class PolicyInterface 
          public:
          virtual void push(int data) = 0;
          virtual int pop() = 0;
          ;

          class VectorPolicy : public PolicyInterface {
          public:
          void push(int data) override

          // ⋯ your implementation here

          ⋮


          and likewise for the ScalarPolicy — derive it from PolicyInterface.



          Now, you can have:



          std::vector<unique_ptr<PolicyInterface>> policies;
          policies.push_back(make_shared<VectorPolicy>());
          policies.push_back(make_shared<ScalarPolicy>());
          ⋮
          policies[i]->push(seven);



          You mentioned policy-based objects with different template parameters in your problem statement. I don’t see any need for a template at all here, but perhaps the concrete example code simply doesn’t show the need?



          The overall idea here is still the right thing. The derived class can be a template, which inherits from the interface. Stated like that, it sounds a lot like what your original code did! But you were deriving a meaningless class from the needed class, not deriving the needed class (which might happen to be templated) from an interface. Since you had virtual functions in the policy classes, I think you were confused and this is what you were trying to do.



          template <typename T, size_t N>
          class FlexPolicy : PolicyInterface
          ⋮
          ;

          policies.push_back( make_unique<FlexPolicy<string,5>> );



          Misc tip: use the std::stack container adaptor instead of a plain vector.



          I like your use of the C++shell web site for holding the code. Too bad it doesn’t have C++17 ☹.







          share|improve this answer













          share|improve this answer



          share|improve this answer











          answered Apr 5 at 3:57









          JDługosz

          5,047731




          5,047731











          • I get it, I didn't take enough time to the example for present correctly the problem. I will create a new question a much better example. PolicyInterface's concept would be the subject of the question where store function pointers in the class. bipll pointed to a mistake.
            – István Simon
            Apr 5 at 7:14











          • std::stack is a FILO solution, but I use hear a FIFO solution. Maybe the std::deque can be better than std::vector, but with small element size the std::vector is faster.
            – István Simon
            Apr 5 at 7:28







          • 1




            You are right, your solution is much better for what the example try to present.
            – István Simon
            Apr 5 at 7:33
















          • I get it, I didn't take enough time to the example for present correctly the problem. I will create a new question a much better example. PolicyInterface's concept would be the subject of the question where store function pointers in the class. bipll pointed to a mistake.
            – István Simon
            Apr 5 at 7:14











          • std::stack is a FILO solution, but I use hear a FIFO solution. Maybe the std::deque can be better than std::vector, but with small element size the std::vector is faster.
            – István Simon
            Apr 5 at 7:28







          • 1




            You are right, your solution is much better for what the example try to present.
            – István Simon
            Apr 5 at 7:33















          I get it, I didn't take enough time to the example for present correctly the problem. I will create a new question a much better example. PolicyInterface's concept would be the subject of the question where store function pointers in the class. bipll pointed to a mistake.
          – István Simon
          Apr 5 at 7:14





          I get it, I didn't take enough time to the example for present correctly the problem. I will create a new question a much better example. PolicyInterface's concept would be the subject of the question where store function pointers in the class. bipll pointed to a mistake.
          – István Simon
          Apr 5 at 7:14













          std::stack is a FILO solution, but I use hear a FIFO solution. Maybe the std::deque can be better than std::vector, but with small element size the std::vector is faster.
          – István Simon
          Apr 5 at 7:28





          std::stack is a FILO solution, but I use hear a FIFO solution. Maybe the std::deque can be better than std::vector, but with small element size the std::vector is faster.
          – István Simon
          Apr 5 at 7:28





          1




          1




          You are right, your solution is much better for what the example try to present.
          – István Simon
          Apr 5 at 7:33




          You are right, your solution is much better for what the example try to present.
          – István Simon
          Apr 5 at 7:33












           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f191207%2freach-c-policy-based-common-interface-with-different-template-parameters-from%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          Chat program with C++ and SFML

          Function to Return a JSON Like Objects Using VBA Collections and Arrays

          Will my employers contract hold up in court?