How to know the number of chain custom-defined operator << calls?

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











up vote
6
down vote

favorite












I have my own class where I define and use << operator like so:



vw& vw::operator<<(const int &a) 

// add a to an internal buffer
// do some work when it's the last number

return *this;


...

vw inst;

inst << a << b << c << d;

...

inst << a << b;

...


The number of chain << calls is different every time. These numbers together represent a code and I need to do something when the code is complete.



Do I have any other options to know when it's complete rather than adding a special terminating value to each chain, like below?



inst << a << b << c << d << term;

...

inst << a << b << term;









share|improve this question



















  • 1




    You'll need a terminator if you go the streaming route. You could make a variadic function and handle doing that in the function.
    – NathanOliver
    4 hours ago















up vote
6
down vote

favorite












I have my own class where I define and use << operator like so:



vw& vw::operator<<(const int &a) 

// add a to an internal buffer
// do some work when it's the last number

return *this;


...

vw inst;

inst << a << b << c << d;

...

inst << a << b;

...


The number of chain << calls is different every time. These numbers together represent a code and I need to do something when the code is complete.



Do I have any other options to know when it's complete rather than adding a special terminating value to each chain, like below?



inst << a << b << c << d << term;

...

inst << a << b << term;









share|improve this question



















  • 1




    You'll need a terminator if you go the streaming route. You could make a variadic function and handle doing that in the function.
    – NathanOliver
    4 hours ago













up vote
6
down vote

favorite









up vote
6
down vote

favorite











I have my own class where I define and use << operator like so:



vw& vw::operator<<(const int &a) 

// add a to an internal buffer
// do some work when it's the last number

return *this;


...

vw inst;

inst << a << b << c << d;

...

inst << a << b;

...


The number of chain << calls is different every time. These numbers together represent a code and I need to do something when the code is complete.



Do I have any other options to know when it's complete rather than adding a special terminating value to each chain, like below?



inst << a << b << c << d << term;

...

inst << a << b << term;









share|improve this question















I have my own class where I define and use << operator like so:



vw& vw::operator<<(const int &a) 

// add a to an internal buffer
// do some work when it's the last number

return *this;


...

vw inst;

inst << a << b << c << d;

...

inst << a << b;

...


The number of chain << calls is different every time. These numbers together represent a code and I need to do something when the code is complete.



Do I have any other options to know when it's complete rather than adding a special terminating value to each chain, like below?



inst << a << b << c << d << term;

...

inst << a << b << term;






c++ visual-c++






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 4 hours ago









Mike Kinghan

27.9k761105




27.9k761105










asked 4 hours ago









user1481126

515




515







  • 1




    You'll need a terminator if you go the streaming route. You could make a variadic function and handle doing that in the function.
    – NathanOliver
    4 hours ago













  • 1




    You'll need a terminator if you go the streaming route. You could make a variadic function and handle doing that in the function.
    – NathanOliver
    4 hours ago








1




1




You'll need a terminator if you go the streaming route. You could make a variadic function and handle doing that in the function.
– NathanOliver
4 hours ago





You'll need a terminator if you go the streaming route. You could make a variadic function and handle doing that in the function.
– NathanOliver
4 hours ago













2 Answers
2






active

oldest

votes

















up vote
5
down vote













You can:



  • Use a special final type to signal termination (a la std::endl).


  • Avoid using operator<<, and defining a variadic template function instead. A variadic template function supports any number of arbitrary arguments, and knows that number at compile-time.



  • Put the logic into vw's destructor, and allow operator<< only on rvalues. E.g.



    vw << a << b << c;
    // `vw::~vw()` contains termination logic






share|improve this answer




















  • This makes LogicStuff's approach a little clearer during usage. Although I'm not sure I've actually seen anyone do it this way as it "looks" a bit weird
    – Lightness Races in Orbit
    3 hours ago

















up vote
4
down vote













It is possible without changing the current syntax.



You will have to make inst << a (i.e. the current operator<<) return a temporary instance of a "special" class, holding a reference to inst, implementing operator<< by calling inst.operator<<, returning reference
to *this, and then doing the extra work in its destructor, which will be called at the end of the statement.



And yes, you can keep track of the call count with it.




I propose these nonmember operator<< overloads (vw_chain is the new proxy class):



// Left-most operator<< call matches this
vw_chain operator<<(vw &inst, const int &a)
vw_chain chain(inst);
chain.insert(a);
return chain;


// All subsequent calls within the << chain match this
vw_chain operator<<(vw_chain chain, const int &a)
chain.insert(a);
return chain;



The class itself:



struct vw_chain

explicit vw_chain(vw &inst) : inst(inst)

~wv_chain()
// do something


void insert(const int &a)
// This, the original operator<<, should be made accessible only to this
// function (private, friend class declaration?), not to cause ambiguity.
// Or, perhaps, put the implementation of the original operator<< here
// and remove it altogether.
inst << a;
++insertion_count;


vw &inst;
size_t insertion_count = 0;
;


We have to pass the instance around by value, but the copying should be optimized out.






share|improve this answer


















  • 3




    However this does sort of modify the "meaning" of << which is expected to do the same thing each time regardless of whether it chains or not. That might be a concern.
    – Lightness Races in Orbit
    3 hours ago










Your Answer





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: "1"
;
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: true,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
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%2fstackoverflow.com%2fquestions%2f52706371%2fhow-to-know-the-number-of-chain-custom-defined-operator-calls%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
5
down vote













You can:



  • Use a special final type to signal termination (a la std::endl).


  • Avoid using operator<<, and defining a variadic template function instead. A variadic template function supports any number of arbitrary arguments, and knows that number at compile-time.



  • Put the logic into vw's destructor, and allow operator<< only on rvalues. E.g.



    vw << a << b << c;
    // `vw::~vw()` contains termination logic






share|improve this answer




















  • This makes LogicStuff's approach a little clearer during usage. Although I'm not sure I've actually seen anyone do it this way as it "looks" a bit weird
    – Lightness Races in Orbit
    3 hours ago














up vote
5
down vote













You can:



  • Use a special final type to signal termination (a la std::endl).


  • Avoid using operator<<, and defining a variadic template function instead. A variadic template function supports any number of arbitrary arguments, and knows that number at compile-time.



  • Put the logic into vw's destructor, and allow operator<< only on rvalues. E.g.



    vw << a << b << c;
    // `vw::~vw()` contains termination logic






share|improve this answer




















  • This makes LogicStuff's approach a little clearer during usage. Although I'm not sure I've actually seen anyone do it this way as it "looks" a bit weird
    – Lightness Races in Orbit
    3 hours ago












up vote
5
down vote










up vote
5
down vote









You can:



  • Use a special final type to signal termination (a la std::endl).


  • Avoid using operator<<, and defining a variadic template function instead. A variadic template function supports any number of arbitrary arguments, and knows that number at compile-time.



  • Put the logic into vw's destructor, and allow operator<< only on rvalues. E.g.



    vw << a << b << c;
    // `vw::~vw()` contains termination logic






share|improve this answer












You can:



  • Use a special final type to signal termination (a la std::endl).


  • Avoid using operator<<, and defining a variadic template function instead. A variadic template function supports any number of arbitrary arguments, and knows that number at compile-time.



  • Put the logic into vw's destructor, and allow operator<< only on rvalues. E.g.



    vw << a << b << c;
    // `vw::~vw()` contains termination logic







share|improve this answer












share|improve this answer



share|improve this answer










answered 4 hours ago









Vittorio Romeo

53.3k16139277




53.3k16139277











  • This makes LogicStuff's approach a little clearer during usage. Although I'm not sure I've actually seen anyone do it this way as it "looks" a bit weird
    – Lightness Races in Orbit
    3 hours ago
















  • This makes LogicStuff's approach a little clearer during usage. Although I'm not sure I've actually seen anyone do it this way as it "looks" a bit weird
    – Lightness Races in Orbit
    3 hours ago















This makes LogicStuff's approach a little clearer during usage. Although I'm not sure I've actually seen anyone do it this way as it "looks" a bit weird
– Lightness Races in Orbit
3 hours ago




This makes LogicStuff's approach a little clearer during usage. Although I'm not sure I've actually seen anyone do it this way as it "looks" a bit weird
– Lightness Races in Orbit
3 hours ago












up vote
4
down vote













It is possible without changing the current syntax.



You will have to make inst << a (i.e. the current operator<<) return a temporary instance of a "special" class, holding a reference to inst, implementing operator<< by calling inst.operator<<, returning reference
to *this, and then doing the extra work in its destructor, which will be called at the end of the statement.



And yes, you can keep track of the call count with it.




I propose these nonmember operator<< overloads (vw_chain is the new proxy class):



// Left-most operator<< call matches this
vw_chain operator<<(vw &inst, const int &a)
vw_chain chain(inst);
chain.insert(a);
return chain;


// All subsequent calls within the << chain match this
vw_chain operator<<(vw_chain chain, const int &a)
chain.insert(a);
return chain;



The class itself:



struct vw_chain

explicit vw_chain(vw &inst) : inst(inst)

~wv_chain()
// do something


void insert(const int &a)
// This, the original operator<<, should be made accessible only to this
// function (private, friend class declaration?), not to cause ambiguity.
// Or, perhaps, put the implementation of the original operator<< here
// and remove it altogether.
inst << a;
++insertion_count;


vw &inst;
size_t insertion_count = 0;
;


We have to pass the instance around by value, but the copying should be optimized out.






share|improve this answer


















  • 3




    However this does sort of modify the "meaning" of << which is expected to do the same thing each time regardless of whether it chains or not. That might be a concern.
    – Lightness Races in Orbit
    3 hours ago














up vote
4
down vote













It is possible without changing the current syntax.



You will have to make inst << a (i.e. the current operator<<) return a temporary instance of a "special" class, holding a reference to inst, implementing operator<< by calling inst.operator<<, returning reference
to *this, and then doing the extra work in its destructor, which will be called at the end of the statement.



And yes, you can keep track of the call count with it.




I propose these nonmember operator<< overloads (vw_chain is the new proxy class):



// Left-most operator<< call matches this
vw_chain operator<<(vw &inst, const int &a)
vw_chain chain(inst);
chain.insert(a);
return chain;


// All subsequent calls within the << chain match this
vw_chain operator<<(vw_chain chain, const int &a)
chain.insert(a);
return chain;



The class itself:



struct vw_chain

explicit vw_chain(vw &inst) : inst(inst)

~wv_chain()
// do something


void insert(const int &a)
// This, the original operator<<, should be made accessible only to this
// function (private, friend class declaration?), not to cause ambiguity.
// Or, perhaps, put the implementation of the original operator<< here
// and remove it altogether.
inst << a;
++insertion_count;


vw &inst;
size_t insertion_count = 0;
;


We have to pass the instance around by value, but the copying should be optimized out.






share|improve this answer


















  • 3




    However this does sort of modify the "meaning" of << which is expected to do the same thing each time regardless of whether it chains or not. That might be a concern.
    – Lightness Races in Orbit
    3 hours ago












up vote
4
down vote










up vote
4
down vote









It is possible without changing the current syntax.



You will have to make inst << a (i.e. the current operator<<) return a temporary instance of a "special" class, holding a reference to inst, implementing operator<< by calling inst.operator<<, returning reference
to *this, and then doing the extra work in its destructor, which will be called at the end of the statement.



And yes, you can keep track of the call count with it.




I propose these nonmember operator<< overloads (vw_chain is the new proxy class):



// Left-most operator<< call matches this
vw_chain operator<<(vw &inst, const int &a)
vw_chain chain(inst);
chain.insert(a);
return chain;


// All subsequent calls within the << chain match this
vw_chain operator<<(vw_chain chain, const int &a)
chain.insert(a);
return chain;



The class itself:



struct vw_chain

explicit vw_chain(vw &inst) : inst(inst)

~wv_chain()
// do something


void insert(const int &a)
// This, the original operator<<, should be made accessible only to this
// function (private, friend class declaration?), not to cause ambiguity.
// Or, perhaps, put the implementation of the original operator<< here
// and remove it altogether.
inst << a;
++insertion_count;


vw &inst;
size_t insertion_count = 0;
;


We have to pass the instance around by value, but the copying should be optimized out.






share|improve this answer














It is possible without changing the current syntax.



You will have to make inst << a (i.e. the current operator<<) return a temporary instance of a "special" class, holding a reference to inst, implementing operator<< by calling inst.operator<<, returning reference
to *this, and then doing the extra work in its destructor, which will be called at the end of the statement.



And yes, you can keep track of the call count with it.




I propose these nonmember operator<< overloads (vw_chain is the new proxy class):



// Left-most operator<< call matches this
vw_chain operator<<(vw &inst, const int &a)
vw_chain chain(inst);
chain.insert(a);
return chain;


// All subsequent calls within the << chain match this
vw_chain operator<<(vw_chain chain, const int &a)
chain.insert(a);
return chain;



The class itself:



struct vw_chain

explicit vw_chain(vw &inst) : inst(inst)

~wv_chain()
// do something


void insert(const int &a)
// This, the original operator<<, should be made accessible only to this
// function (private, friend class declaration?), not to cause ambiguity.
// Or, perhaps, put the implementation of the original operator<< here
// and remove it altogether.
inst << a;
++insertion_count;


vw &inst;
size_t insertion_count = 0;
;


We have to pass the instance around by value, but the copying should be optimized out.







share|improve this answer














share|improve this answer



share|improve this answer








edited 3 hours ago

























answered 4 hours ago









LogicStuff

15.5k63657




15.5k63657







  • 3




    However this does sort of modify the "meaning" of << which is expected to do the same thing each time regardless of whether it chains or not. That might be a concern.
    – Lightness Races in Orbit
    3 hours ago












  • 3




    However this does sort of modify the "meaning" of << which is expected to do the same thing each time regardless of whether it chains or not. That might be a concern.
    – Lightness Races in Orbit
    3 hours ago







3




3




However this does sort of modify the "meaning" of << which is expected to do the same thing each time regardless of whether it chains or not. That might be a concern.
– Lightness Races in Orbit
3 hours ago




However this does sort of modify the "meaning" of << which is expected to do the same thing each time regardless of whether it chains or not. That might be a concern.
– Lightness Races in Orbit
3 hours ago

















 

draft saved


draft discarded















































 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52706371%2fhow-to-know-the-number-of-chain-custom-defined-operator-calls%23new-answer', 'question_page');

);

Post as a guest













































































Comments

Popular posts from this blog

Long meetings (6-7 hours a day): Being “babysat” by supervisor

Is the Concept of Multiple Fantasy Races Scientifically Flawed? [closed]

Confectionery