我正在尝试实现一个可以使用任意数量的std::size_t
变量并相应地使用它们的函数。
我希望能够调用该函数(让我们为了参数调用它Foo
),如下所示:
Foo( some_other_type, 1, 2, 5, 7, 10 );
我尝试了以下内容:
template <typename T, std::size_t... Coords>
T Foo( T tSomething, Coords... coords );
但这不起作用,如果我删除了最后一个参数,因此它是有效的C ++语法,我必须按如下方式调用它Foo<1, 2, 5, 7, 10>( some_other_type );
这不是我想要的。
我可以使用可变参数:
template <typename T>
T Foo( T tSomething, ... );
但是我会失去我正在寻找的类型安全。所以我的问题是,除了使用std::initializer_list<std::size_t>
之外,在C ++ 11中是否有一种方法,这将要求我按如下方式调用Foo
:
Foo( some_other_type, {1, 2, 5, 7, 10} );
并且意味着我无法解压缩参数以构造另一种类型。
编辑:我希望有类似于可变参数模板的原因以及为什么std::initializer_list
或Foo
的递归版本无效,我说我有一个类Bar
,构造函数需要可变数量的参数,具体取决于具体的实例化,我希望做类似以下的事情:
template <typename T, std::size_t... Coords>
T Foo( T tSomething /*, Coords... coords*/ )
{
Bar<sizeof...(Coords)> bar( /*coords...*/ Coords... );
// Do stuff...
return bar.tProperty;
}
但我希望能够如上所述致电Foo
而不是模板列表。
答案 0 :(得分:0)
我发现这个解决方案起初有点违反直觉。你需要一个&#34; typename ... Coords&#34;而不是将它声明为size_t。这是因为您希望编译器填写类型名称。
您可以通过强制将其用作size_t来确保类型安全。
template <typename T, typename... Coords>
T Foo( T tSomething, const Coords... coords )
{
std::array<size_t, sizeof...(Coords)>unpacked_coords {coords...};
for (size_t coord : unpacked_coords)
{
// do stuff
}
return tSomething;
}
您现在可以调用:
Foo( some_other_type, 1, 2, 5, 7, 10 );
如你所愿:)