gpt4 book ai didi

C++ 如何在可移植代码中处理 tr1 和非 tr1 命名空间?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:29:03 25 4
gpt4 key购买 nike

是否有规范的方法来处理在尝试维护 TR1 和非 TR1 工具链之间的可移植代码时出现的命名空间问题?

我有一个 VC++2010 项目 #include <type_traits> .我还有一个 LLVM 3.0 编译器可以很好地处理这个问题。这允许我使用模板,例如:

std::enable_if<typename>
std::is_enum<typename>

但是我还需要在 Xcode 4.5 clang 编译器上构建和维护此代码:

$ /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

这个编译器似乎没有包含文件,而是有一个 .然而,这给我带来了问题,因为 namespace 已从 std::更改为 __gnu_cxx::,这意味着我必须使用:

__gnu_cxx::__enable_if<typename>

我以某种方式能够确定符号 __GLIBCXX__ 的定义足以确定我是否应该使用一个或另一个(甚至不确定这是正确的方法,但现在它在我使用的编译器之间工作)。

所以我可以使用预处理器宏:

#ifdef __GLIBCXX__
# include <tr1/type_traits>
# define ENABLE_IF __gnu_cxx::__enable_if
#else
# include <type_traits>
# define ENABLE_IF std::enable_if
#endif

但这似乎更像是一种 hack 而不是正确的解决方案。 (实际上我试过这个但它不起作用,因为尝试使用 __gnu_cxx::__enable_if 会导致此错误:

error: too few template arguments for class template '__enable_if'
  • 进一步挖掘表明这个版本的 enable_if 实际上有两个模板参数。我现在很迷茫...)

我想过做这样的事情:

#ifdef __GLIBCXX__
# include <tr1/type_traits>
namespace __gnu_cxx = foo;
#else
# include <type_traits>
namespace std = foo;
#endif

... foo::enable_if< ... >

但是这不起作用,因为模板名为 enable_if在一个命名空间中,但是 __enable_if在另一个。

我确定我不是第一个处理这个问题的人 - 有人可以告诉我解决这个问题的行业最佳实践吗?还是我应该改用 Boost?

有一个类似的问题(我认为)但只有部分答案 here .有更好的选择吗?

编辑:我用 <boost/type_traits.hpp> 试过了:

#include <boost/type_traits.hpp>

template <typename ValueType>
class Extractor <ValueType, typename boost::enable_if<boost::is_enum<ValueType>::value>::type> {
public:
ValueType extract(double value) {
return static_cast<ValueType>(static_cast<int>(value)); // cast to int first, then enum, to satisfy VC++2010
}
};

enum MyEnum { Enum0, Enum1 };
Extractor<MyEnum> e;
MyEnum ev = e.extract(1.0);

然而,这在 Xcode 4.5 中给我以下编译器错误:

error: expected a qualified name after 'typename'
class Extractor <ValueType, typename boost::enable_if<boost::is_enum<ValueType>::value>::type> {
^
error: unknown type name 'type'

所以 std::enable_if 和 boost::enable_if 似乎不是直接兼容的。

最佳答案

我会回答我自己的问题,因为我确实使用 boost::enable_if_c 做了一些工作(请注意 std::enable_if 的替代品是 boost::enable_if_c,而不是 boost::enable_if)。

#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_enum.hpp>

// this would work except one of my environments doesn't contain <complex> so it's
// too inclusive. Better (for me) to use the more specific includes above.
// #include <boost/type_traits.hpp>

template <typename ValueType>
class Extractor <ValueType, typename boost::enable_if_c<boost::is_enum<ValueType>::value>::type> {
public:
ValueType extract(double value) {
return static_cast<ValueType>(static_cast<int>(value)); // cast to int first, then enum, to satisfy VC++2010
}
};

但是我仍然很好奇是否有比求助于 Boost 更好的方法来处理这个问题。

关于C++ 如何在可移植代码中处理 tr1 和非 tr1 命名空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14823832/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com