已知类型的C++变分函数模板
C++ Variadic Function Templates of Known Type
我目前正试图了解使用可变模板支持可以做的一些事情。假设我有一个这样的功能-
template <typename ... Args>
void foo(Args ... a)
{
int len = sizeof...(tail);
int vals[] = {a...};
/* Rest of function */
}
/* Elsewhere */
foo(1, 2, 3, 4);
这段代码之所以有效,是因为我事先假设参数将是整数,但如果我提供其他内容,显然会失败。如果我事先知道参数包将包含一个特定的类型,那么有没有什么方法可以在没有模板的情况下使用之类的东西
void foo(int ... a)
我试过这样做,但编译器给出了一个错误,即foo是一个空字段。我知道我也可以通过递归访问包中的参数,但我不确定这是否能解决我的问题——也就是说,我希望能够接受相同类型的可变数量的参数。
这应该有效:
void foo(int);
template<typename ...Args>
void foo(int first, Args... more)
{
foo(first);
foo(more...);
}
如果您以前知道类型,您可以使用std:initializer_list
:的函数重载
#include <initializer_list>
#include <iostream>
void foo( std::initializer_list<int> l )
{
for ( auto el : l )
// do something
}
void foo( std::initializer_list<float> l )
{
}
void foo( std::initializer_list<std::string> l )
{
}
int main()
{
foo( {1, 2, 3, 4 } );
foo( {1.1f, 2.1f, 3.1f, 4.1f } );
foo( { "foo", "bar", "foo", "foo" } );
return 0;
}
如果使用Visual Studio 2012,则可能需要Visual C++编译器2012年11月版CTP。
编辑:如果您仍然想使用可变模板,您可以执行:
template <int ... Args>
void foo( )
{
int len = sizeof...(Args);
int vals[] = {Args...};
// ...
}
// And
foo<1, 2, 3, 4>();
但您必须记住,它不适用于float
和std::string
,例如:您将以'float': illegal type for non-type template parameter
结束。float
作为non-type template parameter
是不合法的,这与精度有关,浮点数无法精确表示,您引用同一类型的可能性可能取决于数字的表示方式。
我目前正试图了解一些我可以使用varadic模板支持做的事情。
假设你想用可变模板进行实验,但没有找到任何问题的解决方案,那么我建议你看看下面的代码:
#include <iostream>
template<int ...Values>
void foo2()
{
int len = sizeof...(Values);
int vals[] = {Values...};
for (int i = 0; i < len; ++i)
{
std::cout << vals[i] << std::endl;
}
}
int main()
{
foo2<1, 2, 3, 4>();
return 0;
}
foo2
和foo
的区别在于,您在运行时将参数传递给foo
,在编译时将参数传给foo2
,因此对于您使用的每个参数集,编译器都会生成单独的foo2
函数体。
顶部答案的变体,如果您喜欢,它将拒绝隐式转换为int
:
#include <type_traits>
void foo(int);
template<typename Arg1, typename ...Args>
void foo(Arg1 first, Args... more)
{
static_assert(std::is_same_v<Arg1, int>, "foo called with non-int argument");
foo(first);
foo(more...);
}
在大多数情况下,使用具有相同类型参数包的可变模板是没有意义的,但在启用c++11的编译器中:
#include <iostream>
#include <tuple>
template <typename ... Args>
void foo(Args ... args) {
using type = typename std::tuple_element<0, std::tuple<Args...>>::type;
const auto len = std::tuple_size<std::tuple<Args...>> {};
type vals[] = {args...};
for (size_t it = 0; it < len; ++it) {
std::cout << vals[it] << std::endl;
}
}
int32_t main(int argc, char** argv) {
foo(1, 2);
foo(1.1, 2.2);
foo("1", "2");
return EXIT_SUCCESS;
}
- 当函数模板参数是具有默认参数的类模板时,函数模板参数的推导如何执行
- 将重载的成员函数传递给函数模板
- C++17中函数模板中的静态数组初始化(MSVC 2019)
- 为什么 gcc 和 clang 为函数模板的实例化生成不同的符号名称?
- 具有常量引用参数的函数模板专用化
- std::span<const T> 作为函数模板中的参数
- 如何编写一个完美的缩写函数模板?
- 仅在函数模板中为那些定义了函数的类型执行函数
- 如何在C++中伪造虚拟可变参数函数模板?
- 以下代码中的函数模板有什么问题?
- 在 C++20 中是否不再允许在 std 中对程序定义类型的函数模板进行专用化?
- 将显式实例化的函数模板与转换匹配
- 使用定义函数模板别名
- 函数模板返回类型
- C++有什么方法可以在既不调用函数模板也不提供其模板参数的情况下引用函数模板?
- C++ std::functional 中的可变参数函数模板
- 单行函数模板 c++ 的内联性保证
- C++函数模板需要 &for 数组参数
- 概念解析为使用 std::make_signed_t 时意外的函数模板
- 两个函数模板候选项.将一个参数作为引用后,选择不太专业的模板