【发布时间】:2018-05-20 03:54:29
【问题描述】:
如何最好地实现一个接受两个std::array<int, [size]> 参数的函数,每个参数的大小约束 由一组在编译时已知的相应值限制?
- 该函数只能接受大小源自给定集合(枚举/宏/等)的数组
- 允许的数组“大小”集将来可能会更改并且可能很大(有效地排除函数重载)
- 无论允许的数组“大小”集发生什么变化,函数本身都应保持固定
问题“Passing a std::array of unknown size to a function”虽然相似,但似乎并不直接适用。
以下在 C++14 中有效,但似乎不必要地冗余和混乱:
#include <type_traits>
#include <array>
// Add legal/allowable sizes for std::array<> "types" here
// Note: Not married to this; perhaps preprocessor instead?
enum class SizesForArrayX : size_t { Three = 3, Four, Forty = 40 };
enum class SizesForArrayY : size_t { Two = 2, Three, EleventyTwelve = 122 };
// Messy, compile-time, value getter for the above enum classes
template <typename S>
constexpr size_t GetSizeValue(const S size)
{ return static_cast<std::underlying_type_t<S>>(size); }
// An example of the function in question; is Template Argument Deduction
// possible here?
// Note: only arrays of "legal"/"allowable" sizes should be passable
template <SizesForArrayX SX, SizesForArrayY SY>
void PickyArrayHandler(
const std::array<int, GetSizeValue(SX)>& x,
const std::array<int, GetSizeValue(SY)>& y)
{
// Do whatever
for (auto& i : x) i = 42;
for (auto& i : y) while (i --> -41) i = i;
}
调用上面的:
int main()
{
// Declare & (value-)initialize some arrays
std::array<int, GetSizeValue(SizesForArrayX::Forty)> x{};
std::array<int, GetSizeValue(SizesForArrayY::Two>) y{};
//PickyArrayHandler(x, y); // <- Doesn't work; C2672, C2783
// This works & handles arrays of any "allowable" size but the required
// template params are repetitions of the array declarations; ick
PickyArrayHandler<SizesForArrayX::Forty, SizesForArrayY::Two>(x, y);
}
...丑陋、不优雅、编译缓慢,并且要求声明的数组大小与传递给PickyArrayHandler 函数模板的显式“大小”相匹配。
对于上面的具体示例:
PickyArrayHandler模板有没有办法推导出传递的数组的大小?一般来说:有不同的更好的方法吗?
【问题讨论】:
-
如果从枚举中删除“类”,则不需要“GetSizeValue”和演员表
-
static_assert在函数内部。 -
@skeller 没有强类型枚举,如何限制数组大小?
-
@Henri 谢谢。我不明白这将如何解决第 2 和第 3 个项目符号
-
@quasinormalized 使用枚举是不可能的。您不能迭代不连续的枚举。
标签: c++ templates c++14 stdarray