如何使用std :: aligned_union

时间:2014-02-05 04:24:13

标签: c++ c++11

在尝试学习如何使用std :: aligned_union时,我无法找到任何示例。我的尝试遇到了一些我不知道如何解决的问题。

struct include
{
    std::string file;
};
struct use
{
    use(const std::string &from, const std::string &to) : from{ from }, to{ to }
    {
    }
    std::string from;
    std::string to;
};
std::aligned_union<sizeof(use), include, use>::type item;
*reinterpret_cast<use*>(&item_) = use{ from, to };

当我尝试在VC ++ 2013调试模式下运行程序时,我在memcpy(unsigned char * dst, unsigned char * src, unsigned long count)中收到运行时错误。我假设这是VC ++实现临时分配的方式。

我如何改变这个以便我没有这个问题?

3 个答案:

答案 0 :(得分:10)

aligned_union类型为您提供适合作为所需类的存储的POD类型 - 它实际上不是该类型的对象。您仍然需要构建自己的对象:

#include <memory>

{
    std::aligned_union<sizeof(use), include, use>::type storage;

    use * p = new (static_cast<void*>(std::addressof(storage))) use(from, to);

    // ...

    p->~use();
}

答案 1 :(得分:5)

扩展Kerrek's answer:我建议使用unique_ptr自定义删除工具自动处理销毁。您可以在工厂(Live at Rextester)中很好地包装所有内容:

struct placement_deleter {
  template <typename T>
  void operator () (T* ptr) const {
    ptr->~T();
  }
};

template <typename T, typename...Args>
std::unique_ptr<T, placement_deleter>
make_in_place(void* place, Args&&...args) {
  return std::unique_ptr<T, placement_deleter>{
    ::new (place) T(std::forward<Args>(args)...)
  };
}

int main() {
  std::aligned_union<0, int, std::string>::type storage;
  {
    auto i = make_in_place<int>(&storage, 42);
    std::cout << *i << '\n';
  }
  {
    auto s = make_in_place<std::string>(&storage, "this is");
    *s += " a test";
    std::cout << *s << '\n';
  }
}

答案 2 :(得分:2)

我也正在扩展Kerrek's answeraligned_union的可能(C ++ 14)实现是:

template <std::size_t Len, class... Types>
struct aligned_union
{
  static constexpr std::size_t alignment_value = std::max({alignof(Types)...});

  struct type
  {
    alignas(alignment_value) char _s[std::max({Len, sizeof(Types)...})];
  };
};

所以很明显:

  • 您必须构建自己的对象( placement new
  • type是一种大小和对齐的POD类型,适合用作Types中列出的任何类型的对象的未初始化存储(但实际上不属于这些类型)
  • 您可以使用0作为Len参数的值(我认为它适用于通用编程情况,例如参见https://stackoverflow.com/a/27069379/3235496

有关详细信息: