Performance vs Readability with optional parameter - c++

Suppose that I have to call same method for each member of a vector contained in a class.
If element-i of the vector has a certain value, I have to modify it.
I've max 10 element in this vector.
What is the best way to do?
- Call a method with an optional parameter?
- Or call a method with an if-else statment inside?
class A {
public:
A();
void doSomething(const string& s) {
if(s=="foo") {
std::cout << s;
} else {
std::cout << s << ".dat"
}
}
void doSomethingDef(const string& s, const string& v = "") {
std::cout << s << v;
}
private:
std::vector<std::string> list_;
}
int main() {
A a;
}
/* Constructor with method 1 */
A::A() {
std::vector<std::string>::iterator i = list_.begin();
for(; i != list_.end(); ++i) {
this->doSomething(*i);
}
}
/* Constructor with method 2 */
A::A() {
this->doSomethingDef(list[0]);
this->doSomethingDef(list[1]);
this->doSomethingDef(list[2]);
this->doSomethingDef(list[3]);
this->doSomethingDef(list[4], ".dat");
this->doSomethingDef(list[5], ".dat");
this->doSomethingDef(list[6]);
this->doSomethingDef(list[7]);
this->doSomethingDef(list[8]);
this->doSomethingDef(list[9]);
}

If you have a max of 10 elements, I'm going to claim that performance is completely irrelevant anyway.
Furthermore, until you have proven that performance really matters, method 1 is so much more readable that you should prefer it anyway.
Finally, because of the way cout operations work, I would guess that in this little example, method 2 is actually slower, because it's faster to do a branch and a comparison with a fixed string than doing an additional call to a formatted output function.

In C++11 your constructor with method 1 could be written as:
A::A()
{
for(const auto & listElement : list_)
{
this->doSomething(listElement);
}
}
Performance and readability and a bit more generic to boot. Or you could do it with a std::for_each and a lambda function which may trigger a compiler with optimizations turned on to unroll that loop for you.
A::A()
{
for_each(begin(list_), end(list_),[this](const std::string & listElement)
{
doSomething(listElement);
});
}

If you decided to use something similar to your second method (not that I'm advising it, just considering how to do it if you were to), I'd strongly consider using overloading instead of a default parameter:
void doSomethingDef(const string& s) {
std::cout << s;
}
void doSomethingDef(const string &s, const string &v) {
std::cout << s << v;
}
With a default parameter, you're still creating a temporary string and passing it as the second parameter, then making all the iostreams calls to insert that string into the stream even though it has no effect. By using overloading instead, you avoid all the processing necessary to create, pass, and insert the second string (except when you really have a second string to display, of course).
Mixing that with I/O (and only writing 10 strings anyway) probably covers up most of the benefit from this, so it'll probably be hard to even measure, not to mention notice in real life. On the other hand, if you were generating a lot of strings and (for example) depositing the output in memory instead of writing it to output, the difference could start to become substantial.

Related

C++ distinguish Lambdas from Function pointers inside a vector

I'm writing a little event manager class where I store some function pointers inside a vector. I use std::function<void(int)> as vector type, I tested inserting inside it lambdas and normal functions and it works:
void t(int p){
/*things*/
}
[...]
event.bind([](int p){/*things*/});
event.bind(t);
Now, (at a certain point I need to delete lambdas but not functions,) my question is:
Is it possible to distinguish lambdas from functions? If yes, how?
EDIT:
Since I clarified my doubts, this question becomes just what the title says
The real answer is: you don't want to do this. It defeats the point of type-erasing functors if you actually want to know the original type also in case of whatever. This just smells like bad design.
What you are potentially looking for is std::function::target_type. This is a way to pull out the underlying type_info of the target function that the function object is storing. Each type_info has a name(), which can be demangled. Note that this is a very deep rabbit hole and you're basically going to have to hard-code all sorts of weird edge-cases. As I've been doing thanks to Yakk's very loving help.
Different compilers mangle their lambda names differently, so this approach doesn't even resemble portability. Quick checking shows that clang throws in a $ while gcc throws {lambda...#d}, So we can attempt to take advantage of that by writing something like:
bool is_identifier(std::string const& id) {
return id == "(anonymous namespace)" ||
(std::all_of(id.begin(), id.end(),
[](char c){
return isdigit(c) || isalpha(c) || c == '_';
}) && !isdigit(id[0]));
}
bool is_lambda(const std::type_info& info)
{
std::unique_ptr<char, decltype(&std::free)> own {
abi::__cxa_demangle(info.name(), nullptr, nullptr, nullptr),
std::free
};
std::string name = own ? own.get() : info.name();
// drop leading namespaces... if they are valid namespace names
std::size_t idx;
while ((idx = name.find("::")) != std::string::npos) {
if (!is_identifier(name.substr(0, idx))) {
return false;
}
else {
name = name.substr(idx+2);
}
}
#if defined(__clang__)
return name[0] == '$';
#elif defined(__GNUC__)
return name.find("{lambda") == 0;
#else
// I dunno?
return false;
#endif
}
And then throw that in your standard erase-remove idiom:
void foo(int ) { }
void bar(int ) { }
long quux(long x) { return x; }
int main()
{
std::vector<std::function<void(int)>> v;
v.push_back(foo);
v.push_back(bar);
v.push_back(quux);
v.push_back([](int i) { std::cout << i << '\n';});
std::cout << v.size() << std::endl; // prints 4
v.erase(
std::remove_if(
v.begin(),
v.end(),
[](std::function<void(int)> const& f){
return is_lambda(f.target_type());
}),
v.end()
);
std::cout << v.size() << std::endl; // prints 3
}
No, not in general.
A std::function<void(int)> can store a function pointer to any function that can be called by passing a single rvalue int. There are an infinite number of such signatures.
The type of a lambda is an unique anonymous class for each declaration. Two distinct lambdas do not share any type relationship.
You can determine of a std::function<void(int)> stores a variable of a specific type, but in both the function pointer and lambda case there is an unbounded number of different types that can be stored in the std::function to consider. And you can only test for "exactly equal to a type".
You can access the type id information, but there is no portable representation there, and generally using that information for anything other than identity matching (and related) or debugging is a bad idea.
Now, a restricted version of the question (can you tell if a std::function<void(int)> contains a function pointer of type void(*)(int)) is easy to solve. But in general, doing so remains a bad idea: first, because it is delicate (code far away from the point you use it, like a subtle change to the function signature, can break things), and second, inspecting and changing your behavior based on the type stored in a std::function should only be done in extreme corner cases (usually involving updating your code from using void* style callbacks to std::function style callbacks).
Be it a function pointer or lambda, it ends up as a std::function<void(int)> in the vector. It is then std::function<void(int)>'s responsibility to manage the function pointer or lambda, not yours. That means, you just remove the std::function<void(int)>s you want from the vector. The destructor of std::function<void(int)> knows how to do things right. In your case, that would be doing nothing with function pointers and invoking the destructor of lambdas. std::function<void(int)> enables you to treat different things in a nice and uniform way. Don't misuse it.
NOTE: This answer presupposes that there is a finite, distinct number of function signatures that may be assigned as event handlers. It assumes that assigning any-old function with the wrong signature is a mistake.
You can use std::function::target to determine which ones are the function pointers and by process of elimination figure out which ones must be the lambdas:
void func1(int) {}
void func2(double) {}
int main()
{
std::vector<std::function<void(int)>> events;
events.push_back(func1);
events.push_back([](int){});
events.push_back(func2);
for(auto& e: events)
{
if(e.target<void(*)(int)>())
std::cout << "funcion int" << '\n';
else if(e.target<void(*)(double)>())
std::cout << "funcion double" << '\n';
else
std::cout << "must be lambda" << '\n';
}
}
This works because std::function::target returns a null pointer if the parameter type doesn't match.
Single variable example:
void func(int) {}
int main()
{
std::function<void(int)> f = func;
if(f.target<void(*)(int)>())
std::cout << "not a lambda" << '\n';
}

declaring a pointer or a stack variable

Assume we have the following case:
If it is morning mood is good otherwise mood is bad
Print the mood
it could be written as:
std::string mode; //this cost us calling the constructor of std::string
if(time==Morning){ // a real code should be here
mood="Good"//re assign the string
}
else{
mood="bad"//re assign the string
}
std::cout << mood;
assuming it is not std::string, it is a very big object. Isn't it too luxury to declare "mode" and call the constructor for no reason!
Is using the raw pointer a solution? what is the best practice here?
thanks
You could use the ternary operator to initialize the string.
std::string mode = (time == Morning ? "Good" : "Bad")
As MSalters pointed out in the comments this is actually still two constructions(constructor + copy) but it should get optimized by the compiler. You can directly initialize the string with
std::string mode { (time == Morning ? "Good" : "Bad") };
I would consider putting the logic into a separate function. This helps to keep functions small and simple.
std::string moodAtTime(Time time)
{
if(time==Morning)
{ // a real code should be here
return "Good";
}
else
{
return "bad";
}
}
std::string mood = moodAtTime(t);
This reduces function length and splits the code into small units performing simple questions.
If it is only for initialization, you can use a lambda to do it without the named function:
std::string mood = [](Time t)
{
if(t==Morning)
{
return "Good";
}
else
{
return "bad";
}
}(now);
The cost gets high if you enter that specific scope allot of times, and yes, it could get very expensive (depending on the what's happening inside the scope) .
The solution would be to keep either a global variable, or more widely used, a pool of such objects (object pools / memory are widely used for such purposes, especially in the case of small and very small objects).
So, to explain in code
// scope that is entered allot, like 100k times per second
{
std::string temp;
...
// magic happens
...
}
Quick solution
{
static std::string g_uniqueNamed_temp_string;
...
// magic happens
...
}
Elegant solution
EDIT : switched to raw pointers to avoid copying
{
std::string* tempString = StringPool::GetAPreallocatedString();
...
// magic happens
...
}
You can use alloca for that:
#include <iostream>
#include <sstream>
using namespace std::literals;
int main() {
void *mem = alloca(sizeof(std::string)); //Allocates memory on stack; no initialization
std::string *mood;
if(true){ // a real code should be here
mood = new (mem) std::string("Good");//re assign the string
}
else{
mood=new (mem) std::string("Bad");//re assign the string
}
std::cout << *mood;
return 0;
}

c++ stringstream to ostream to string

I would like to be able to do:
foo(stringstream()<<"number = " << 500);
EDIT: single line solution is crucial since this is for logging purposes. These will be all around the code.
inside foo will print the string to screen or something of the sort.
now since stringstream's operator<< returns ostream&, foo's signature must be:
foo(ostream& o);
but how can I convert ostream& to string? (or char*).
Different approaches to achieving this use case are welcome as well.
The obvious solution is to use dynamic_cast in foo. But the given
code still won't work. (Your example will compile, but it won't do what
you think it should.) The expression std::ostringstream() is a
temporary, you can't initialize a non-const reference with a temporary,
and the first argument of std::operator<<( std::ostream&, char const*)
is a non-const reference. (You can call a member function on a
temporary. Like std::ostream::operator<<( void const* ). So the code
will compile, but it won't do what you expect.
You can work around this problem, using something like:
foo( std::ostringstream().flush() << "number = " << 500 );
std::ostream::flush() returns a non-const reference, so there are no
further problems. And on a freshly created stream, it is a no-op.
Still, I think you'll agree that it isn't the most elegant or intuitive
solution.
What I usually do in such cases is create a wrapper class, which
contains it's own std::ostringstream, and provides a templated
member operator<< which forwards to the contained
std::ostringstream. Your function foo would take a const
reference to this—or what I offen do is have the destructor call
foo directly, so that the client code doesn't even have to worry about
it; it does something like:
log() << "number = " << 500;
The function log() returns an instance of the wrapper class (but see
below), and the (final) destructor of this class calls your function
foo.
There is one slight problem with this. The return value may be copied,
and destructed immediately after the copy. Which will wreck havoc with
what I just explained; in fact, since std::ostringstream isn't
copyable, it won't even compile. The solution here is to put all of the
actual logic, including the instance of std::ostringstream and the
destructor logic calling foo in a separate implementation class, have
the public wrapper have a boost::shared_ptr to it, and forward. Or
just reimplement a bit of the shared pointer logic in your class:
class LogWrapper
{
std::ostringstream* collector;
int* useCount;
public:
LogWrapper()
: collector(new std::ostringstream)
, useCount(new int(1))
{
}
~LogWrapper()
{
-- *useCount;
if ( *useCount == 0 ) {
foo( collector->str() );
delete collector;
delete useCount;
}
}
template<typename T>
LogWrapper& operator<<( T const& value )
{
(*collector) << value;
return *this;
}
};
Note that it's easy to extend this to support optional logging; just
provide a constructor for the LogWrapper which sets collector to
NULL, and test for this in the operator<<.
EDITED:
One other thing occurs to me: you'll probably want to check whether the
destructor is being called as a result of an exception, and not call
foo in that case. Logically, I'd hope that the only exception you
might get is std::bad_alloc, but there will always be a user who
writes something like:
log() << a + b;
where the + is a user defined overload which throws.
I would suggest you to use this utility struct:
struct stringbuilder
{
std::stringstream ss;
template<typename T>
stringbuilder & operator << (const T &data)
{
ss << data;
return *this;
}
operator std::string() { return ss.str(); }
};
And use it as:
void f(const std::string & s );
int main()
{
char const *const pc = "hello";
f(stringbuilder() << '{' << pc << '}' );
//this is my most favorite line
std::string s = stringbuilder() << 25 << " is greater than " << 5 ;
}
Demo (with few more example) : http://ideone.com/J995r
More on my blog : Create string on the fly just in one line
You could use a proxy object for this; this is a bit of framework, but if you want to use this notation in a lot of places then it may be worth it:
#include <iostream>
#include <sstream>
static void foo( std::string const &s )
{
std::cout << s << std::endl;
}
struct StreamProxy
{
std::stringstream stream;
operator std::string() { return stream.str(); }
};
template <typename T>
StreamProxy &operator<<( StreamProxy &s, T v )
{
s.stream << v;
return s;
}
static StreamProxy make_stream()
{
return StreamProxy();
}
int main()
{
foo( make_stream() << "number = " << 500 );
}
This program prints
number = 500
The idea is to have a little wrapper class which can be implicitely converted into a std::string. The << operator is simply forwarded to the contained std::stringstream. The make_stream() function is strictly speaking not necessary (you could also say StreamProxy(), but I thought it looks a bit nicer.
A couple of options other than the nice proxy solution just presented by Frerich Raabe:
Define a static string stream variable in the header that defines the logging function and use the comma operator in your invocation of the logging function so that this variable is passed rather than the ostream& returned by the stream insertion operator. You can use a logging macro to hide this ugliness. The problem with this solution is that it is a bit on the ugly side, but this is a commonly used approach to logging.
Don't use C++ I/O. Use a varargs C-style solution instead. Pass a format string as the first argument, with the remaining arguments being targets for that format string. A problem with this solution is that even if your compiler is smart enough to ensure that printf and its cousins are safe, the compiler probably won't know that this new function is a part of the printf family. Nonetheless, this is also a commonly used approach.
If you don't mind using macros functions, you can make the logging function accept const string&, and use the following macro
#define build_string(expr) \
(static_cast<ostringstream*>(&(ostringstream().flush() << expr))->str())
And suppose you foo has signature void foo(const string&), you only need the one-liner
foo(build_string("number = " << 500))
This was inspired by James Kanze's answer about static_cast and stringstream.flush. Without the .flush() the above method fails with unexpected output.
Please note that this method should not leak memory, as temporary values, whether in the pointer form or not, are still allocated on the stack and hence destroyed upon return.
Since you're converting to string anyways, why not
void foo(const std::string& s)
{
std::cout << "foo: " << s << std::endl;
}
...
std::stringstream ss;
ss << "number = " << 500;
foo(ss.str());
This is not possible. As the name ostream implies, it is used for output, for writing to it. You could change the parameter to stringstream&. This class has the method str() which returns a std::string for your use.
EDIT I did not read the issue with operator << returning ostream&. So I guess you cannot simply write your statements within the functions argument list but have to write it before.
You can create a small wrapper around std::ostringstream that will convert back to std::string on use, and have the function take a std::string const &. The first approach to this solution can be found in this answer to a different question.
On top of that, you can add support for manipulators (std::hex) if needed.

prohibiting instantiation as a temporary object (C++)

I like using sentry classes in c++, but I seem to have a mental affliction that results in repeatedly writing bugs like the following:
{
MySentryClass(arg);
// ... other code
}
Needless to say, this fails because the sentry dies immediately after creation, rather than at the end of the scope, as intended. Is there some way to prevent MySentryClass from being instantiated as a temporary, so that the above code either fails to compile, or at least aborts with an error message at runtime?
I can't think of an automatic way to detect if you make this mistake or not. You could always create a macro that expands to the correct thing and use that to declare the sentry instead if you keep using it wrong.
#define MY_SENTRY_CLASS(_X) MySentryClass _sentry(_X)
and then use
MY_SENTRY_CLASS(arg);
or put a post-it on your monitor to remind you.
The only thing you could do is make the constructors private and force access through a helper function. This is far less similar than the initial construction syntax and less likely to be mistaken. You could also allocate on the heap (still a waste) but it's much easier to spot. However, if you want your class to be constructible, you can't stop people constructing rvalues of that type.
Edit: IF you know that MySentryClass always takes an argument, you could disallow construction AND and only allow operator=(arguments). This would force you to do
MySentryClass x;
x = arg;
You could do some kind of method chain for it.
MySentryClass x;
x.SetArg1(arg).SetArg2(arg2).construct();
No, there is no exit from this problem. To make objects on the stack, you have to have public constructors, and if you have public constructors, you can make the mistake you are reporting.
Not sure you'll like this solution, but the solution may well be grep:
find /path/to/project -type f -name \*.cpp -print0 | xargs grep -0 'MySentryClass('
Another thing you could do is use sed or perl to preprocess your source file, replacing MySentryClass( with \n#error MySentryClass used incorrectly\n, which hopefully will give you a line number that's close to where the error is. How to do this depends on your build system.
I think the #define is the best method.
But just as an option for not using #define:
Main
int main()
{
try
{
S arg1;
// This will not compile
// MySentry x1 = MySentry::CreateSentry(arg1);
S arg3;
MySentry x2(MySentry::CreateSentry(arg3));
S arg2;
// This will not compile
// MySentry(arg2);
S arg4;
// This will generate a runtime exception
// It will never call start() or end()
//MySentry::CreateSentry(arg4);
}
catch(std::exception const& e)
{
std::cout << "Exception : " << e.what() << "\n";
}
}
Edited. Now works better.
#include <stdexcept>
#include <iostream>
class S
{
public:
void start() {std::cout << "Start\n";}
void end() {std::cout << "End\n";}
};
class MySentry
{
struct Init
{
Init(S& s) : arg(s),bad(true) {}
~Init() {if (bad) {throw std::runtime_error("Bad usage of MySentry");}}
S& arg;
mutable bool bad;
};
public:
static Init CreateSentry(S& arg) { return Init(arg);}
explicit MySentry(Init const& arg)
: obj(arg.arg)
, bad(false)
{
arg.bad = false;
std::cout << "Created\n";
obj.start();
}
MySentry(MySentry const& rhs)
: obj(rhs.obj)
, bad(false)
{
std::cout << "Copied (this may not appear)\n";
std::cout << "If the optimizer kicks in then the copy may be elided.\n";
// But if it did not optimize out then
// We have to mark the temporaty as bad
// And not call end() in its destructor.
// Note: Never call start() here as it will always be called in the
// main private constrctor above
rhs.bad = true;
}
~MySentry()
{
if (!bad)
{
// Everything working
obj.end();
}
std::cout << "Destroyed\n";
}
private:
S& obj;
mutable bool bad;
};
What you are trying to do is perfectly legal in C++ and I don't think there is a way to disallow it.

Efficient push_back of classes and structs

I've seen my colleague do the second snippet quite often. Why is this? I've tried adding print statements to track the ctors and dtors, but both seem identical.
std::vector<ClassTest> vecClass1;
ClassTest ct1;
ct1.blah = blah // set some stuff
...
vecClass1.push_back(ct1);
std::vector<ClassTest> vecClass2;
vecClass2.push_back(ClassTest());
ClassTest& ct2 = vecClass2.back();
ct2.blah = blah // set some stuff
...
PS. I'm sorry if the title is misleading.
Edit:
Firstly, thank you all for your responses.
I've written a small application using std::move. The results are surprising to me perhaps because I've done something wrong ... would someone please explain why the "fast" path is performing significantly better.
#include <vector>
#include <string>
#include <boost/progress.hpp>
#include <iostream>
const std::size_t SIZE = 10*100*100*100;
//const std::size_t SIZE = 1;
const bool log = (SIZE == 1);
struct SomeType {
std::string who;
std::string bio;
SomeType() {
if (log) std::cout << "SomeType()" << std::endl;
}
SomeType(const SomeType& other) {
if (log) std::cout << "SomeType(const SomeType&)" << std::endl;
//this->who.swap(other.who);
//this->bio.swap(other.bio);
this->who = other.who;
this->bio = other.bio;
}
SomeType& operator=(SomeType& other) {
if (log) std::cout << "SomeType::operator=()" << std::endl;
this->who.swap(other.who);
this->bio.swap(other.bio);
return *this;
}
~SomeType() {
if (log) std::cout << "~SomeType()" << std::endl;
}
void swap(SomeType& other) {
if (log) std::cout << "Swapping" << std::endl;
this->who.swap(other.who);
this->bio.swap(other.bio);
}
// move semantics
SomeType(SomeType&& other) :
who(std::move(other.who))
, bio(std::move(other.bio)) {
if (log) std::cout << "SomeType(SomeType&&)" << std::endl;
}
SomeType& operator=(SomeType&& other) {
if (log) std::cout << "SomeType::operator=(SomeType&&)" << std::endl;
this->who = std::move(other.who);
this->bio = std::move(other.bio);
return *this;
}
};
int main(int argc, char** argv) {
{
boost::progress_timer time_taken;
std::vector<SomeType> store;
std::cout << "Timing \"slow\" path" << std::endl;
for (std::size_t i = 0; i < SIZE; ++i) {
SomeType some;
some.who = "bruce banner the hulk";
some.bio = "you do not want to see me angry";
//store.push_back(SomeType());
//store.back().swap(some);
store.push_back(std::move(some));
}
}
{
boost::progress_timer time_taken;
std::vector<SomeType> store;
std::cout << "Timing \"fast\" path" << std::endl;
for (std::size_t i = 0; i < SIZE; ++i) {
store.push_back(SomeType());
SomeType& some = store.back();
some.who = "bruce banner the hulk";
some.bio = "you do not want to see me angry";
}
}
return 0;
}
Output:
dev#ubuntu-10:~/Desktop/perf_test$ g++ -Wall -O3 push_back-test.cpp -std=c++0x
dev#ubuntu-10:~/Desktop/perf_test$ ./a.out
Timing "slow" path
3.36 s
Timing "fast" path
3.08 s
If the object is more expensive to copy after "set some stuff" than before, then the copy that happens when you insert the object into the vector will be less expensive if you insert the object before you "set some stuff" than after.
Really, though, since you should expect objects in a vector to be copied occasionally, this is probably not much of an optimization.
If we accept that your colleague's snippet is wise, because ClassTest is expensive to copy, I would prefer:
using std::swap;
std::vector<ClassTest> vecClass1;
ClassTest ct1;
ct1.blah = blah // set some stuff
...
vecClass1.push_back(ClassTest());
swap(ct1, vecClass1.back());
I think it's clearer, and it may well be more exception-safe. The ... code presumably allocates resources and hence could throw an exception (or else what's making the fully-built ClassTest so expensive to copy?). So unless the vector really is local to the function, I don't think it's a good idea for it to be half-built while running that code.
Of course this is even more expensive if ClassTest only has the default swap implementation, but if ClassTest doesn't have an efficient swap, then it has no business being expensive to copy. So this trick perhaps should only be used with classes known to be friendly, rather than unknown template parameter types.
As Gene says, std::move is better anyway, if you have that C++0x feature.
If we're worried about ClassTest being expensive to copy, though, then relocating the vector is a terrifying prospect. So we should also either:
reserve enough space before adding anything,
use a deque instead of a vector.
The second version benefits from moving the temporary. The first version is copying the temporary vector. So the second one is potentially faster. The second version has also potentially smaller peak memory requirements, the first version creates two objects one temporary and one copy of it and only then deletes the temporary. You can improve the first version by explicitly moving the temporary:
std::vector<ClassTest> vecClass1;
ClassTest ct1;
ct1.blah = blah // set some stuff
...
vecClass1.push_back(std::move(ct1));
You should probably ask your collegue to know exactly why, but we can still take a guess. As James pointed out, it might be a tad more efficient if the object is more expensive to copy once constructed.
I see advantages in both versions.
I like your collegue's snippet because: although there are 2 objects in both cases, they only co-exist for a very short period of time in the second version. There is only one object available for editing: this avoids the potential error of editing ct1 after push_back.
I like your personal snippet because: invoking push_back to add a second object potentially invalidates the reference ct2, inducing a risk of undefined behavior. The first snippet does not present this risk.
They are identical (as far as I can see). Maybe he or she does that as an idiomatic custom.