是否允许为 std::array 定义专门化?它会导致未定义的行为吗?

Aja*_*iya 5 c++ stdarray

我正在一个有类的图书馆工作foofoo有一个不平凡的构造函数。当我创建std::arrayof foo( std::array<foo, 10>) 时,构造函数被调用 10 次。我想实现一种单独的方式来初始化foo. 定义专业化是否会std::array<foo, N>导致未定义的行为或任何其他问题?如果可以的话,我的专业需要具备哪些属性?

https://en.cppreference.com/w/cpp/language/extending_std表示允许自定义类型的专业化,除非明确禁止,并且https://en.cppreference.com/w/cpp/container/array没有说什么关于它。

use*_*522 10

是的,您可以专门std::array<foo, N>针对程序定义的foo. 然而,这有很多问题,这里只给出两个主要的问题:

  1. 的每个用户都std::array<foo, N>必须在第一次使用实例化之前包含部分特化std::array<foo, N>。否则行为是未定义的。因此,如果一个翻译单位或库std::array<foo, N>在不包含专业化的情况下使用,就会遇到问题。即使从更实际的角度(而不是标准的 UB)来看,在这种情况下,库/翻译单元之间也可能存在 ABI 中断。换句话说,放置专业化的唯一安全位置是在库内提供的标foo中。

  2. 您的专业化必须满足该标准对std::array. 这些要求之一是std::array聚合类型。这意味着您无法为该类提供自定义构造函数,从而使您的目标变得不可能。

相反,定义您自己的容器类型,使其按照您想要的方式运行,尽管我质疑您到底在想什么。很可能您想要的东西很复杂,std::vector并且它会更好地为您服务。有时,std::vector分配最大大小的完全堆栈也很好,但标准库没有。但是,可以使用自定义堆栈分配器和std::vector.

  • 感谢你的回答!1. 是的,我计划将 array&lt;foo, N&gt; 和 foo 作为库的一部分。2.我没有意识到要求之一是我不能定义构造函数。这真是太糟糕了。我想我只会实现一个 `make_foo_array&lt;N&gt;()` ,它返回哨兵类型的初始值设定项列表,或者只是创建一个单独的容器类型。 (2认同)
  • @AjayBrahmakshatriya 我认为甚至没有任何根本不同的方法来实现符合标准要求的“std::array”。它基本上必须是给定类型和大小的内置数组的包装器,没有任何特殊的成员函数。您最多可以争论的是是否允许添加其他未使用的成员,但这毫无意义。 (2认同)
  • 这就说得通了。我想要的只是添加一个新的构造函数,但我知道这是不允许的。我将创建一个单独的容器。谢谢 (2认同)