Using TR1 libraries in GCC and MSVC
Asked Answered
W

4

10

I would like to use the TR1 libraries that ship with modern versions of GCC and MSVC, but there are subtle differences: in GCC, I have to say

#include <tr1/memory>
std::tr1::shared_ptr<int> X;

while in MSVC I have to say

#include <memory>
std::shared_ptr<int> X;

I have two questions: 1) Does MSVC automatically operate in C++0x-mode (equivalent to GCC's std=c++0x), or does it also work in C++98/03 mode by default? 2) How can I unify the includes and namespaces? I was thinking about a preprocessor macro of the sort "INCLUDE_TR1(memory)" or something like that.

To clarify, I want to use the traditional, standard C++98/03; not C++0x (otherwise there'd be no problem).

I'd be most grateful for any suggestions!

Wrestle answered 10/5, 2011 at 15:34 Comment(2)
std::tr1::shared_ptr works on my MSVC10.Gamber
MF: Thank you. TG: The most general answer you can give would be appreciated!Wrestle
W
2

OK, after having several inconsistent and unsurmountable problems with Boost.TR1, especially when trying to use GCC's native TR1 libraries, I decided to ditch Boost entirely and use a small #define workaround. Here is my "tr1.h":

#ifndef _TR1_INCLUDE_H
#define _TR1_INCLUDE_H

/** Usage: #include TR1INCLUDE(unordered_map)
 **
 ** Configuration: Define HAVE_TR1_SUBDIR if you need #include <tr1/unordered_map>; otherwise we take #include <unordered_map>.
 **
 **/

#define QUOTE(arg) <arg>

#ifdef HAVE_TR1_SUBDIR
#  define TR1IFY(arg) tr1/arg
#else
#  define TR1IFY(arg) arg
#endif

#define TR1INCLUDE(arg) QUOTE(TR1IFY(arg))

#endif

Now I can just write my programs like this:

#include "tr1.h"
#include TR1INCLUDE(unordered_map)
Wrestle answered 10/5, 2011 at 21:17 Comment(0)
C
4
  1. VC++ 2010 only operates in C++0x mode; previous versions had no C++0x support. That said, much of the standard library in VC++ 2010 is is still based on TR1 (e.g. std::result_of<> uses the TR1 result_of protocol instead of being decltype-based); in fact, much of the standard library in VC++ 2010 is not actually defined in namespace std, but rather in namespace std::tr1 and pulled into namespace std with a using directive.
  2. Use Boost.TR1 -- it will #include the appropriate headers according to your platform, or if your platform doesn't have TR1 support, #include the corresponding Boost implementations and pull them into namespace std::tr1 with using declarations.
Cathern answered 10/5, 2011 at 15:39 Comment(6)
Thank you! But I'm told (buy the Windows people) that "std::tr1::shared_ptr" doesn't work; they have to use std::shared_ptr. Am I maybe misremembering that? If the namespace could always be taken as "std::tr1", then that'd already be half the weight off the problem.Wrestle
@Kerrek SB : I'm not sure what you're saying; in VC++ 2010, there is no definition of std::shared_ptr<>, only a definition of std::tr1::shared_ptr<> that is pulled into namespace std with a using directive. So, of course using std::tr1::shared_ptr<> is safe.Cathern
OK, I didn't know that, since I don't have the compiler. I thought somebody told me that in order to make my GCC code work they had to replace <tr1/memory> by <memory> and std::tr1::shared_ptr by std::shared_ptr, but they may just not have tested std::tr1::shared_ptr. Thanks a lot for clarifying this!Wrestle
Visual Studio 2008 with the TR1 patch requires the tr1 in the namespace. But, IIRC, it's GCC that requires tr1 in the header path, and Visual Studio 2008 with the Tr1 patch that just adds the new stuff to the old header.Brentwood
We're using CMake. I'm now playing with Boost.TR1. I find Boost with CMake, and I add "-D BOOST_HAS_GCC_TR1" to the GCC options (and no changes to the MSVC options), and I turn all headers into C++0x style (<unordered_map> etc.). Fingers crossed.Wrestle
@Kerrek SB : Correct regarding #includes; with GCC you need <tr1/memory> whereas with VC++ 2008 SP1 or VC++ 2010 you need <memory>. But, that's half the purpose of Boost.TR1 -- it #includes the correct headers for you depending on platform.Cathern
V
4

VC++ 2010 always operates in C++0x mode, but the classes exist in both the std and std::tr1 namespaces. You’ll have to detect the compiler with an #if _MSC_VER to choose which headers to include (see this answer).

The Boost.TR1 library can automatically include your compiler’s headers and fill in any missing functionality using Boost. It might help.

Viceroy answered 10/5, 2011 at 15:41 Comment(1)
Thank you for all the answers, and the tip about Boost.TR1! Now whose answer shall I accept?Wrestle
W
2

OK, after having several inconsistent and unsurmountable problems with Boost.TR1, especially when trying to use GCC's native TR1 libraries, I decided to ditch Boost entirely and use a small #define workaround. Here is my "tr1.h":

#ifndef _TR1_INCLUDE_H
#define _TR1_INCLUDE_H

/** Usage: #include TR1INCLUDE(unordered_map)
 **
 ** Configuration: Define HAVE_TR1_SUBDIR if you need #include <tr1/unordered_map>; otherwise we take #include <unordered_map>.
 **
 **/

#define QUOTE(arg) <arg>

#ifdef HAVE_TR1_SUBDIR
#  define TR1IFY(arg) tr1/arg
#else
#  define TR1IFY(arg) arg
#endif

#define TR1INCLUDE(arg) QUOTE(TR1IFY(arg))

#endif

Now I can just write my programs like this:

#include "tr1.h"
#include TR1INCLUDE(unordered_map)
Wrestle answered 10/5, 2011 at 21:17 Comment(0)
T
1

The different versions of MSVC have the features they have. There is no way of turning them on or off.

Some of them might also have both tr1 and std versions of some features. With slightly different semantics!

Tophet answered 10/5, 2011 at 15:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.