接受相同类型的可变数量的参数

时间:2014-07-13 11:32:37

标签: c++ templates c++11 variadic-templates

我正在尝试实现一个可以使用任意数量的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_listFoo的递归版本无效,我说我有一个类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而不是模板列表。

1 个答案:

答案 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 );

如你所愿:)