Even though overuse of getter and setter functions can be frowned upon, they can
help a lot if you’re looking to provide a intuitive api. However the overhead
the additional function call introduces is undesirable. Thankfully, there’s the
inline keyword. It tells the compiler to replace each invocation of the
function with the body of the function.
12345678910111213141516171819
structFoo{intm_number=123;inlineintnumber(){returnm_number;}};intmain(){Foofoo;// used like a regular functionstd::cout<<foo.number()<<std::endl;// compiled to almost identical assembly as thisstd::cout<<foo.m_number<<std::endl;return0;}
However the inline keyword isn’t a guarantee that the compiler will do this.
It’s more of a hint to the compiler. So keep in mind that the compiler is free
to ignore the fact that a function is declared inline and it can inline
functions that haven’t been delcared as such. But in examples similar to the one
above, you can assume it will behave as expected.
Another important piece of information is that the function definition needs to
be available in every translation unit.
foo.h
1
inlineintfoo();
foo.cpp
12345
#include "foo.h"intfoo(){return123;}
If I try to use the foo function by including foo.h I’d get a warning
telling me that the foo is not defined. This won’t prevent compilation, but
the function will not get inlined. The compiler needs access to the
function body to replace it with the call site. There’s a simple solution
though. Just put the function definition in the header.
foo.h
123
inlineintfoo(){return123;}
One finall note. Using inline too much can not only make your binary much
bigger, but it can also slow it down due to the way things are cached during
execution. So only use them on very small functions (1-3 lines) and you should
be good.
One of the things I really like about dynamic languages like javascript & python
is the repl. After you’ve gotten used to that type of exploratory programming,
it’s hard to go back to the edit/compile/run cycle.
Luckily that has finally changed with
cling. It’s an interactive C++
environment that behaves pretty much like a repl. In my recent projects I’ve
been adding a new make rule: repl which lets me interactively play with the
code I’m working on and it has drastically improved my productivity.
Here’s how I set it up. Compiling cling is the first step. Below are how I did
it on OSX.
1234567891011121314151617181920212223242526
brew install gcc
brew install make
# Check out the sources:mkdir src
cd src
svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
cd llvm/tools
svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
svn co http://root.cern.ch/svn/root/trunk/cint/cling cling
cd ..
# Apply some patchescat tools/cling/patches/* | patch -p0
# Configure, build and install themcd ..
mkdir build
cd build
../llvm/configure --enable-targets=host
make
make install
Next there’s an init_repl.cpp file I keep in the root
of my project. It’s responsible for pulling in all the required headers and
doing some initial setup. For the setup, I use C++’s version of a static block.
init_repl.cpp
1234567891011
#include <my_project.h>#include <iostream>#include <string>structReplInit{ReplInit(){std::cout<<"initializing some stuff"<<std::endl;}};staticReplInitrepl_init;
After that you should just be able to run make repl and you’ll be dropped into
a shell where you can dynamically explore you project. I’ve only been using it
for a little while and I’m hooked. I look forward to the day where every project
supports make && make repl.
Marks are a feature that I’ve never really used enough.
Hopefully writing about them will change that for the better.
Make a basic, file local, mark called a
1
ma
Jump back to that mark
1
'a
Now I try to be pragmatic. So use cases are what motivate me to learn new thing.
I think that marks are a good replacement for a lot of the things I use visual
line
V mode for now.
Editing
Lets say a have some text
1234
this
is
a
test
I want to remove lines 2-3.
Currently I’ll jump into visual line mode, select
the lines and then d to delete them.
1
Vjd
If I was going to do same thing with marks I’d set a mark on line 2 ma, go
down a line j, go to the end of that line $, and then delete , go to the
end of that line $, and then delete everything back to the mark d'a.
1
maj$d'a
… not so great.
the best way would be 2dd to delete the 2 lines. I guess there’s no point
trying to use marks for manipulating entire lines. They’re more usefull when
you want to do more complicated motions where you’re not trying to grab the
entire line. Or maybe when the content you are targetting is very large and
visual mode would obscure the view. I’m lazy and don’t feel like coming up with
examples for those situations. So next to another use case.
Jumping
I think marks are more important in the case of navigation than in editing.
Before I say anything else, you need to know that there are 2 different types
of marks: Local abcde.... and Global ABCD.... Local marks are local to the
file they are defined in. If a mark b exists in file1 and then you define
mark b in file2, they can both exist oblivious to eachother. Global marks
are shared across files.
A good usage would be when your trying to debug some C function and you’re
always jumping between the usage, declaration, and definitions. You could just
set global marks for those points.
Undo is a very awesome thing. But most of the time it’s only used for reverting
changes made. What about movement? You know those times when you accidentally
hit some key and your cursor jumps to a completely different part of the page?
'' is your friend. It’s a special mark that denotes the last place you jumped
from. It will keep jumping back and forth between the last 2 locations you were.
But say you did something really retarded and need to go back 3 jumps? In that
case you need to bust out CTRL-O and his buddy CTRL-I. These will navigate
forward and backward through the jump history.
CTRL-O and CTRL-I are the undo and redo when it comes to movement.
Listing
listing doesn’t really make sense as a heading when the other two are taken into
account, but w.e. The way you list all the marks (global and local) is with the
:marks command.
Last Mod
One last thing that you want to do is jump back to the last place you edited
something. That’s what the . mark is for. .' will take you back to your last
edit location.
Line or Char?
Ok so I left out a small tidbit of information, but it’s not that complicated.
When you access a mark using ' then you will jump to the beginning of the line
where the mark was defined. If you want to jump to the exact character where the
mark was created, then you need to use “`.
// 5 second timeoutstructtimevaltimeout={5,0};// recv timeoutintsetopt_result_1=setsockopt(socket_fd,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout));// send timeoutintsetopt_result_2=setsockopt(socket_fd,SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout,sizeof(timeout));// error checkif(setopt_result_1<0||setopt_result_2<0)throw"failed to set timeout";
It seems that logging in C++ isn’t a much discused topic when compared to a language like java. In a recent C++ project, I needed to add real logging support. Up till this point, the following was good enough (don’t judge).
glog was my first choice because it’s the simplest one to set up and it has hardly any dependencies. The interface is also nice to use.
1
LOG(INFO)<<"this is a test"<<123;
If you need simple and robust logging in a standalone application then glog is the way to go. However if you’re using it in a library and want to let your users configure logging options, it starts getting problematic. You can only initialze glog once, so having your library set its own default can get more complicated than it should be.
I didn’t get too far with this library. It’s simply overwhelming! If you want simple logging then it can do that.
1
BOOST_LOG_TRIVIAL(info)<<"this is a test"<<123
But if you want anything more, get ready to read a LOT of documentation.
Boost.Log is more a framework to build your own logging library as opposed to a logging library in an of itself.
I’m not a big fan of java and initially I wasn’t too thrilled about the idea of something that copies log4j. Another thing that turned me off was that it has some pretty heavy dependencies. I eventually decided to give it a try and it wasn’t all that bad.
123
log4cxx::LoggerPtrlogger(log4cxx::Logger::getLogger("bar.foo"));LOG4CXX_INFO(logger,"this is a test"<<123);
The advantage here is that you can configure the system anywhere.
All loggers inherit from the root logger log4cxx::Logger::getRootLogger().
In my example, bar is foo’s parent. So any setting given to bar will be inherited by foo.
custom wrapper
Soon after starting my search I came up with an awesome idea. Why not just build my own, back-end agnostic, wrapper. Then provide an abstract Logger interface which the user can extend with the underlying logging back end. This would be both flexible and let me make my own beautiful api.
1
log::error<<"this is a test"<<123;
… just don’t do it. Doing it right is harder than it seems.
Conclusion
I ended up going with log4cxx. In my opinion, it strikes a nice balance between flexibility and simplicity.
Looking for a way to create a class which behaved like one of the std::ostream classes
123
MyClassobj;obj<<"foo"<<123<<some_string.c_str();
Problem
Implementing all those operator<< overloads would be redundant because something like std::stringstream already does it. However inheriting from std::stringstream is more complicated than it should be.
123
structMyClass:publicstd::stringstream{/* not that simple ... */};
Solution
You can use a simple template to achive the desired effect.