Reputation: 13575
I have a preprocessing code to choose which vector class is used as following:
#define USE_BOOST_VECTOR
#ifdef USE_BOOST_VECTOR
#include <boost/container/vector.hpp>
#define VECTOR boost::container::vector
#else
#include <vector>
#define VECTOR std::vector
#endif
I am not sure if this is a good way. And how about if I have more options to choose, what should I do?
Figured out if there are more options
#define USE_MY_VECTOR 1
#define USE_BOOST_VECTOR 2
#define USE_STD_VECTOR 3
#define CHOOSE_VECTOR USE_BOOST_VECTOR
#if CHOOSE_VECTOR == USE_MY_VECTOR
#include "Vector.h"
#define VECTOR Vector
#elif CHOOSE_VECTOR == USE_BOOST_VECTOR
#include <boost/container/vector.hpp>
#define VECTOR boost::container::vector
#elif CHOOSE_VECTOR == USE_STD_VECTOR
#include <vector>
#define VECTOR std::vector
#endif
But I need to define 1, 2, 3, and more for more options. Just for a brain work, any better way?
Upvotes: 1
Views: 770
Reputation: 305
This is a bad idea, as preprocessors serve a completely different purpose than the one you are using them for. More specifically, they are used to extend the language you are working in. This could be for something as simple as making aliases to the commands in the language, or something as complicated as adding a new semantic constructs to the language, such as adding object oriented programming capability to a procedural language. At any rate, it is not to choose which class libraries to load into your program at compile-time. My suggestion would be to create an interface class, then have two classes inherit from this class. One class will act as a wrapper for boost vector and the other as a wrapper for the std::vector. This way you would not only be able to choose the implementation at compile-time (statically), but also at run-time (dynamically).
See the following link for more details: OOP a good explaination
Upvotes: 0
Reputation: 44468
Don't use pre-processor macros unless you have no other choice - typedefs, constants and if really needed, templates usually can have the intended result, while being much safer.
Now, unless you have a really good reason to prefer Boost vectors over std::vector, go with std::vector. Why? Because if you don't know what you want, what the std namespace provides should be more than enough.
EDIT: Like leemes says, you would need C++11 to make use of templated type aliases.
#define USE_BOOST_VECTOR
#ifdef USE_BOOST_VECTOR
#include <boost/container/vector.hpp>
template <typename T> using VECTOR = boost::container::vector<T>;
#else
#include <vector>
template <typename T> using VECTOR = std::vector<T>;
#endif
// ....
// You could then use it with
VECTOR<int> vec;
Finally, here is some more information on templated typedef aliases
If you don't have a C++11 compiler, you could use namespace aliases:
#define USE_BOOST_VECTOR
#ifdef USE_BOOST_VECTOR
#include <boost/container/vector.hpp>
namespace Container = boost::container;
#else
#include <vector>
namespace Container = std;
#endif
//And use it with...
Container::vector<int> vec;
I also need to add here, that the above method can lead to some very confusing results. I highly recommend that you basically decide up front which vector implementation you'd like to go with and getting rid of your pre-processor macro once and for all. Your code will thank you over time :)
Upvotes: 2