我有一个模板函数,它接受可变数量的参数。由于你不能强制参数属于某种类型,我希望至少强制参数的数量不要高于编译时确定的数字(例如10)。
如果带参数包的模板函数的参数个数高于编译时确定的值,是否可以使编译器发出错误?
template <class ...Args>
void setRequestArguments(const Args&... args)
{
const std::vector<QGenericArgument> vec = { args... };
qDebug() << sizeof...(args);
// Do stuff...
// for (unsigned i = 0; i < vec.size(); ++i) {
// qDebug() << vec[i].name();
// }
}
我想用它来代替QMetaObject::invokeMethod
包装函数中所有参数的通用容器。
答案 0 :(得分:21)
要在参数太多时使函数不可调用,可以使用sfinae约束函数。这样,如果有另一个接受更多参数的重载,编译器将能够选择正确的重载。
具有条件的简单std::enable_if
就足够了:
template <class ...Args, std::enable_if_t<(sizeof...(Args) <= 10)>* = nullptr>
void setRequestArguments(Args&&... args)
{
const std::vector<QGenericArgument> vec = { std::forward<Args>(args)... };
}
为了便于阅读,您可以将约束放在函数的尾随返回类型中:
template <class ...Args>
auto setRequestArguments(Args&&... args) -> std::enable_if_t<(sizeof...(args) <= 10)>
{
const std::vector<QGenericArgument> vec = { std::forward<Args>(args)... };
}
编辑:我添加了转发引用而不是const引用,因为它可以加快程序速度,对非可复制类型更友好。
答案 1 :(得分:15)
如果带参数包的模板函数的参数个数高于编译时确定的值,是否可以使编译器发出错误?
是的,请使用static_assert
:
template <class ...Args>
void setRequestArguments(const Args&... args)
{
static_assert(sizeof...(args) <= 10, "You can't have more than 10 arguments!");
//Stuff...
}