【问题标题】:Detect template presence at compilation time在编译时检测模板是否存在
【发布时间】:2010-05-09 15:10:00
【问题描述】:

最高 4.5 的 GCC 没有标准 C++0x 类型特征模板 has_nothrow_move_constructor。我可以在我的包中使用它进行优化,但我不想排除常见的编译器之一,也不想用HAVE_STD_HAS_NOTHROW_MOVE_CONSTRUCTOR 之类的符号重载配置。是否有可能以某种方式使用该模板(如果存在),如果不存在 without 则使用任何预定义的配置符号回退到复制?我也不想依赖 Boost,因为我的库很小,并且出于任何其他原因不需要 Boost。

在伪代码中,我需要类似:

template <typename type>
struct has_nothrow_move_constructor_robust
  : public integral_constant <bool,
           /* if possible */  has_nothrow_move_constructor <type>::value
           /* otherwise   */  false>
{ };

由于无论如何移动构造函数仅适用于 C++0x,我不介意在上述定义中使用其他 C++0x 功能,如果可能的话。

【问题讨论】:

  • Boost 的大部分是在头文件中实现的,而不是在目标文件中。因此,如果你坚持这些,你不会为你不使用的东西支付尺寸惩罚 - 也不会为你使用的大多数东西支付任何费用。
  • 更多的是依赖(即使几乎每个人都使用 Boost)。也许我可以撕掉 Boost 的相关部分,但因为我的库无论如何都像 3 个标题......
  • 似乎很难检查一个类型是否存在。但是,如果没有移动构造函数,C++0x 一般不会自动回退到复制吗?或者如果 nothrow 部分很重要,是不是很难想象一个复制比移动更安全的类(如果后者没有标记 nothrow)?
  • @UncleBens:是的,如果没有匹配的函数(在本例中为构造函数)接受右值引用,C++0x 会在复制时回退(使用左值引用)。我也无法提出一个逻辑用例,其中复制构造函数不会抛出,但移动构造函数会。但是,我不会将图书馆建立在这样的假设之上。

标签: c++ configuration templates c++11


【解决方案1】:

boost::variant 有一个 has_nothrow_move 的实现供其内部使用 - 您可以使用它,尽管它不像正确的编译器实现那样可靠。它的来源是here - 我不知道它有多可靠,所以YMMV。

除此之外,您可以测试编译器版本宏 (__GNUC__ and __GNUC_MINOR__) 以确定存在,如果不存在则将其存根。不幸的是,似乎任何已发布的 G++ 版本都不支持 has_nothrow_move_constructor,因此您必须稍等片刻才能知道要使用的正确版本。

【讨论】:

    猜你喜欢
    • 2015-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-16
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    相关资源
    最近更新 更多