具有固定数量的参数的函数由整数确定

Jan*_*nis 18 c++ function c++11 c++14 c++17

我有一个类,其模板接受一个整数:

template <unsigned int N>
class Example {};
Run Code Online (Sandbox Code Playgroud)

我正在寻找一种方法来定义一个(成员)函数,它接受一些Example对象作为参数.金额将由N,确定,因此函数将使用如下:

Function(Example<2>(), Example<2>());
Function(Example<3>(), Example<3>(), Example<3>());
Run Code Online (Sandbox Code Playgroud)

到目前为止我尝试了什么:

使用初始化列表,可以将一组对象传递给函数:

template <unsigned int N>
void Function(std::initializer_list<Example<N>> list);
//...
Function({Example<2>(), Example<2>()});
Run Code Online (Sandbox Code Playgroud)

但是,除了真正只传递一个参数(列表)之外的问题是,使用此方法可以使用任意数量的参数:

Function({Example<2>()});
Run Code Online (Sandbox Code Playgroud)

我也尝试使用可变参数函数:

template <unsigned int N>
void Function(Example<N> e...)
{
    va_list args;
    va_start(args, e);
    //...
}
Function(Example<2>(), Example<2>());
Run Code Online (Sandbox Code Playgroud)

这使得可以使用真实参数,但仍然存在使用任意数量参数的问题,并且不可能知道实际传递了多少参数.

Mas*_*nes 21

假设您希望从Example<N>类型中推断出参数的数量,并且所有参数都Example<I>应该共享相同的数量N,那么C++ 17解决方案可能是

template <unsigned int... I>
auto Function( Example<I>... ) ->
    std::enable_if_t<( ( I == sizeof...(I) ) && ... )>
{
   // or static_assert() if you always want an error
}
Run Code Online (Sandbox Code Playgroud)


Vit*_*meo 5

创建Function一个可变参数模板std::enable_if_t用来约束它:

  • 某些IsExample特征可用于确保所有参数都是实例Example

  • sizeof...(pack) 可用于获取参数包的大小

template <unsigned int N, typename... Ts>
auto Function(Ts... xs) 
    -> std::enable_if_t<(IsExample<Ts>::value && ...) 
                     && (sizeof...(Ts) == N)>
{
}
Run Code Online (Sandbox Code Playgroud)

wandbox上的实例


use*_*670 5

您应该使用variadic函数模板和static_assert.与涉及enable_if此方法的方法不同,如果传递的参数不正确,则会产生可读的错误消息

template<unsigned int ... I>
void Function(Example<I>... items)
{
    static_assert
    (
        true && (... && (static_cast<unsigned int>(sizeof...(I)) == I))
    ,   "This function accepts N arguments of type Example<N>"
    );
}
Run Code Online (Sandbox Code Playgroud)

在线编译器