Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using C++ classes like function that may be defined in several different locations

Tags:

c++

c++11

tr1

Between C++0x, C++03 TR1 and boost some things like function and bind can be defined in 3 different places depending on the compiler, eg for VC pre VC9 feature pack you have the boost versions, then you get them in but in the std::tr1:: namespace, and VC10 moves that to just the std:: namespace.

Currently my existing code uses the older boost versions in the boost:: namespace exclusivly, however since for many of my applications and libaries all the boost stuff I used is now in tr1 and C++0x, id like if possible remove the boost dependency from those, while retaining backwards compatibility with older compiler versions.

However I'm not sure on how to make my code locate, include and then be able to access the correct versions :( One thing I have considered is using macros like _MSC_VER to see if the compiler includes the classes I want, (falling back to tr1 and then to boost as needed) and then use the "using somenamespace::someclass;" stuff to move the classes in question into the std:: namespace.

The problem is it seems that in some cases this might break stuff, and I'm not even sure how to tell if VC9 has its feature pack or SP1 installed or not :( I'm also not sure on a tidy way to do it, perhaps provide my own functional.hpp that does the required "magic"?

The main thing is I want to start writing my code for the new standards, but in a way that it will still work with minimal effort on older compilers.

like image 284
Fire Lancer Avatar asked Mar 02 '11 00:03

Fire Lancer


People also ask

Can a function be called from more than one place within a program?

The same function can be accessed from several different places within a program. Once the function has carried out its intended action, control is returned to the point from which the function was accessed.

How many classes can be defined in a program?

How many classes can be defined in a single program? Explanation: Any number of classes can be defined inside a program, provided that their names are different. In java, if public class is present then it must have the same name as that of file. 10.

What is polymorphism C++?

Polymorphism means "many forms", and it occurs when we have many classes that are related to each other by inheritance. Like we specified in the previous chapter; Inheritance lets us inherit attributes and methods from another class. Polymorphism uses those methods to perform different tasks.

What is called when a function is defined outside a class?

A public member function can also be defined outside of the class with a special type of operator known as Scope Resolution Operator (SRO); SRO represents by :: (double colon)


2 Answers

Boost.TR1 already does this for you – it has compiler/version detection logic to use your compiler's TR1 implementation if it's available for your platform, or use the various relevant Boost libraries to emulate TR1 if not:

This library does not itself implement the TR1 components, rather it's a thin wrapper that will include your standard library's TR1 implementation (if it has one), otherwise it will include the Boost Library equivalents, and import them into namespace std::tr1.

like image 152
ildjarn Avatar answered Oct 26 '22 13:10

ildjarn


From your post it seems like you are primarily concerned about VC++. If thats the case, then I think using preprocessor defines based on the _MSC_VER is probably the most straight forward solution. As you hinted at, just find out what versions were first to provide the various features and include the appropriate header.

As far as how to access them in your code, I would just use several typedefs that are set to different types depending on the included header. If the boost, tr1, and C++0x versions of the libraries provide the same (or similar enough) interfaces, this should "just work". Although, if the type is a class template, plain typedefs won't work, and you'll have to resort to a #define.

Sometimes straight forward is good. It may not be worth making it too complicated. (If you want to support more than just VC++, you will probably have to get complicated.)

Perhaps something like this (as a first thought):

#ifdef _MSC_VER
  #if _MSV_VER >= VERSION_WITH_CXX0X
    #include <function>
    #define FUNCTION_NAMESPACE std
  #elif _MSV_VER >= VERSION_WITH_TR1
    #include <tr1/function>
    #define FUNCTION_NAMESPACE std::tr1
  #else
    #include <boost/function.hpp>
    #define FUNCTION_NAMESPACE boost
#else
  #error The current compiler is not supported.
#endif

void func();

FUNCTION_NAMESPACE::function<void ()> funcobj(func);

Although I don't like using a #define to get the namespace, I can't think of another way off the top of my head. I bet there is one, though.

like image 34
dappawit Avatar answered Oct 26 '22 13:10

dappawit