19

我惊讶地发现它is_swappable<T>不在is_nothrow_swappable<T>新的 C++11 type_traits 元函数中。它们noexcept对于模板的传播和确定是否可以为模板实现非抛出交换非常有用。

libc++ 推出自己的内部版本:请参阅其 type_traits 版本中的__is_swappable 和 __is_nothrow_swappable ,它在内部广泛使用它们,但不会使它们在库之外可用。

我最终将我自己的版本拼凑在一起用于个人项目,这似乎可行,但我确信它以某种方式损坏了。

我很好奇这两个的缺席,因为它们似乎很重要。这个特性是在 C++11 标准化过程中考虑的,还是只是疏忽没有包含在内?如果考虑,是什么导致它没有被纳入最终标准(缺乏时间、实施问题等)?是否有缺陷报告或进化论文讨论这个问题?有没有计划在 C++1Y 中加入这些特性?某处是否有公认的“正确”版本?

4

1 回答 1

14

is_swappable<T>并且is_nothrow_swappable<T>从未为 C++11 提出过。这是它们不在 C++11 中的主要原因。即没有被提议就没有任何东西可以进入。

那么为什么没有提出这些建议呢?

从个人经验来看,我不会提出任何我没有实施并发现有用的东西。尽管我确实为 libc++ 实现了它们,但在 C++11 发布之前我并没有这样做。我根本没有时间和工具来为 C++11 这样做。我最好的猜测是其他任何人都是如此。

很高兴你发现这些有用。 可能是为下一个 C++ 标准提出建议的人!严重地!我们需要你的帮助!

更新

回应:

不过,这有点小技巧,因为这仅在根据移动构造函数和赋值运算符实现交换时才有效

下面的测试表明它在 libc++ 的实现中的表现:

#include <type_traits>
#include <iostream>

struct A
{
    A(const A&);
};

struct B
{
};

void swap(B&, B&);

struct C
{
};

void swap(C&, C&) noexcept;

struct D
{
    D(const D&) noexcept;
    D& operator=(const D&) noexcept;
};

int main()
{
    std::cout << "std::__is_nothrow_swappable<int>::value = "
              << std::__is_nothrow_swappable<int>::value << '\n';
    std::cout << "std::__is_nothrow_swappable<A>::value = "
              << std::__is_nothrow_swappable<A>::value << '\n';
    std::cout << "std::__is_nothrow_swappable<B>::value = "
              << std::__is_nothrow_swappable<B>::value << '\n';
    std::cout << "std::__is_nothrow_swappable<C>::value = "
              << std::__is_nothrow_swappable<C>::value << '\n';
    std::cout << "std::__is_nothrow_swappable<D>::value = "
              << std::__is_nothrow_swappable<D>::value << '\n';
}

对我来说输出:

std::__is_nothrow_swappable<int>::value = 1
std::__is_nothrow_swappable<A>::value = 0
std::__is_nothrow_swappable<B>::value = 0
std::__is_nothrow_swappable<C>::value = 1
std::__is_nothrow_swappable<D>::value = 1
于 2013-01-23T16:05:57.590 回答