Note that there are some explanatory texts on larger screens.

plurals
  1. POC++ how to handle tr1 and non-tr1 namespaces in portable code?
    text
    copied!<p>Is there a canonical way to deal with the namespace issues that arise when trying to maintain portable code between a TR1 and non-TR1 toolchain?</p> <p>I have a VC++2010 project that <code>#include &lt;type_traits&gt;</code>. I also have an LLVM 3.0 compiler that can handle this fine. This allows me to use templates such as:</p> <pre><code>std::enable_if&lt;typename&gt; std::is_enum&lt;typename&gt; </code></pre> <p>However I also need to build and maintain this code on an Xcode 4.5 clang compiler:</p> <pre><code>$ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang --version Apple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn) Target: x86_64-apple-darwin11.4.2 Thread model: posix </code></pre> <p>This compiler doesn't seem to have a include file, instead it has a . However this is causing me problems because the namespace has changed from std:: to __gnu_cxx::, meaning I have to use:</p> <pre><code>__gnu_cxx::__enable_if&lt;typename&gt; </code></pre> <p>Somehow I was able to determine that the definition of the symbol <code>__GLIBCXX__</code> is sufficient to determine whether I should use one or the other (not even sure that's the right way to do it, but for now it works between the compilers I'm using).</p> <p>So I could resort to using preprocessor macros:</p> <pre><code>#ifdef __GLIBCXX__ # include &lt;tr1/type_traits&gt; # define ENABLE_IF __gnu_cxx::__enable_if #else # include &lt;type_traits&gt; # define ENABLE_IF std::enable_if #endif </code></pre> <p>But this seems like it might be more of a hack than a proper solution. (Actually I tried this and it doesn't work, because trying to use <code>__gnu_cxx::__enable_if</code> causes this error:</p> <pre><code>error: too few template arguments for class template '__enable_if' </code></pre> <ul> <li>further digging suggests that this version of enable_if actually takes two template arguments. I'm now very lost...)</li> </ul> <p>I thought about doing something like:</p> <pre><code>#ifdef __GLIBCXX__ # include &lt;tr1/type_traits&gt; namespace __gnu_cxx = foo; #else # include &lt;type_traits&gt; namespace std = foo; #endif ... foo::enable_if&lt; ... &gt; </code></pre> <p>However this doesn't work because the template is called <code>enable_if</code> in one namespace, but <code>__enable_if</code> in the other.</p> <p>I'm sure I'm not the first person to deal with this problem - can someone point me at the industry best practice for resolving this please? Or should I just use Boost instead?</p> <p>There is a similar question (I think) but only a partial answer <a href="https://stackoverflow.com/a/7095608/143397">here</a>. Are there better options?</p> <p>EDIT: I tried this, with <code>&lt;boost/type_traits.hpp&gt;</code>:</p> <pre><code>#include &lt;boost/type_traits.hpp&gt; template &lt;typename ValueType&gt; class Extractor &lt;ValueType, typename boost::enable_if&lt;boost::is_enum&lt;ValueType&gt;::value&gt;::type&gt; { public: ValueType extract(double value) { return static_cast&lt;ValueType&gt;(static_cast&lt;int&gt;(value)); // cast to int first, then enum, to satisfy VC++2010 } }; enum MyEnum { Enum0, Enum1 }; Extractor&lt;MyEnum&gt; e; MyEnum ev = e.extract(1.0); </code></pre> <p>However this gives me the following compiler error in Xcode 4.5:</p> <pre><code>error: expected a qualified name after 'typename' class Extractor &lt;ValueType, typename boost::enable_if&lt;boost::is_enum&lt;ValueType&gt;::value&gt;::type&gt; { ^ error: unknown type name 'type' </code></pre> <p>So it doesn't seem that std::enable_if and boost::enable_if are drop-in compatible. </p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload