【问题标题】:Partial template specialization for: std::allocator_traits?部分模板特化:std::allocator_traits?
【发布时间】:2021-03-02 22:05:47
【问题描述】:

是否可以像这样专门化 std::allocator_traits, 模板?

namespace falloc_ {

  template<class Tp> class FAllocator ;

}

// partial spec for all falloc_::FAllocator<U>, std::allocator_traits

template<typename Tp> 
struct std::allocator_traits<falloc_::FAllocator<Tp> > {

 using allocator_type = falloc_::FAllocator<Tp> ;
 using value_type = typename allocator_type::value_type ;

 // ...
 // All the components I need here, I will include all the code if You need them.
 // ...

} ;


namespace falloc_ {

  template<class Tp> class FAllocator {

    public:
       using value_type = Tp ;
  
  } ;

}

完整代码在std++20分配器类和分配器、特征类(std::allocator_traits)规范下编译运行。在那种情况下,我的问题实际上是关于实际正确性,无论是根据对标准了解更多的人,是否禁止类似的要素类重载,还是只是假设因为(完整)代码是可编译和可执行的,并且根据预期的计划 - 我可以考虑使用它吗?

另外,我用代码测试了分配器:

  std::vector<int, falloc_::FAllocator<int> > mv ;

  for (size_t i = 0 ; i < 5 ; i++) {
    mv.push_back(i) ;
  }

  for (int i = 4 ; i > -1 ; i--) {
    std::cout << "mv[" << i << "]: " << mv[i] << '\n' ;
  }

内存已正确分配和释放,我还检查了 Valgrind。 使用 Gdb,我检查并调用了所有函数

std::allocator_traits<falloc_::FAllocator<U> > // U aka int for std::vector<int, falloc_::FAllocator<int> > 

提前感谢您提供的任何见解、建议和建议。

【问题讨论】:

    标签: c++ traits allocator specialization


    【解决方案1】:

    允许专门化std::allocator_traits 模板。见[namespace.std]/2:

    除非明确禁止,否则程序可以将任何标准库类模板的模板特化添加到命名空间std,前提是 (a) 添加的声明依赖于至少一个程序定义的类型并且 (b) 特化满足原始模板的标准库要求。

    没有明确禁止专门化std::allocator_traits,因此您可以为您定义的类型FAllocator 这样做。此规则适用于完全专业化和部分专业化。

    请记住,您的专业化必须确实满足原始模板的所有要求。该标准已经指定了每个成员类型的定义和每个成员函数的行为,以至于如果您要编写自己的特化,它基本上与原来的相同,这违背了这样做的目的。我想您可以在不违反原始要求的情况下将日志语句添加到std::allocator_traits&lt;...&gt;::construct(...),但将这些日志语句放入分配器本身会更容易。如果您坚持将它们放在您的 allocator_traits 专业化中,您还必须小心不要与 [dcl.constexpr]/7 发生冲突。

    我看不出任何情况下专门化 std::allocator_traits 是有意义的。

    【讨论】:

    • 感谢您的回答。我还要感谢您提供了很好的文档来阐明该主题并描述了这些问题。最终,我想使用我自己的内存堆或内存竞技场。我已经有一些偏移指针的实现,我需要使用 c++ 17/20 标准。在标准 17/20 中,函数 'std :: allocator <...> ::construct' 正在从分配器级别被放弃,转而支持 std :: allocator_traits 中的函数 'consructs' 是尝试重载 allocator_traits 的另一个原因,
    • 我问只是因为我认为它不会起作用。我通常对处理与并发编程相关的较低级别的内存感兴趣。
    • 我想在理论大纲中了解这些问题,以便以后能够更实际地创建基于分配器概念的代码,同时帮助其他程序员,如果它对某人有用。跨度>
    • @Vacuum allocator_traits&lt;A&gt;::construct 函数调用 A::construct。您应该在通用代码中实现A::construct,但使​​用 allocator_traits&lt;A&gt;::construct。
    猜你喜欢
    • 2014-06-13
    • 1970-01-01
    • 1970-01-01
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-06
    • 1970-01-01
    相关资源
    最近更新 更多