我是模板的新手,我真的不理解为什么这不起作用。我希望向量将使用这些值来构建。
main.cpp
template <typename ...T>
void int_printf(T ...args)
{
std::vector<T> vec = {args...};
for(auto& v:vec)
{
std::cout << v << std::endl;
}
}
int main()
{
int_printf(1,2,3,4);
return 0;
}
预期结果
1
2
3
4
msvc编译器错误 (已翻译)
src/main.cpp(35): error C3520: 'T': the parameter pack must be expanded in this context
src/main.cpp(37): error C3536: '<begin>$L0': can't be used before initialization
src/main.cpp(37): error C3536: '<end>$L0': can't be used before initialization
src/main.cpp(37): error C2100: invalid redirection
答案 0 :(得分:5)
您的代码中的问题在于T
在此上下文中不是模板参数,而是模板参数包,在您的示例中将扩展为T=[int,int,int,int]
。 std::vector
希望将类型作为模板参数而不是模板参数包传递。您可以使用std::common_type
解决此问题:
#include<type_traits>
template <typename ...T>
void int_printf(T ...args)
{
//use std::common_type to deduce common type from template
// parameter pack
std::vector<typename std::common_type<T...>::type> vec = {args...};
for(auto& v:vec)
{
std::cout << v << std::endl;
}
}
您应该注意,只有在传递给int_printf
的参数具有通用类型的情况下,这才起作用。
答案 1 :(得分:3)
另一种较为罗word的方法是添加一个初始模板参数,指定vec
的类型,如下所示:
#include <iostream>
#include <vector>
template <typename T, typename ... Args>
void int_printf(Args ... args)
{
std::vector<T> vec = {args...};
for (auto& v : vec)
{
std::cout << v << std::endl;
}
}
int main()
{
int_printf<int>(1,2,3,4);
return 0;
}
如果将不兼容类型的列表传递给int_printf
,这可能会给出更清晰的错误消息。
答案 2 :(得分:2)
当您执行std::vector<T>
时,T
不是单一类型,而是一组类型。您不能将其用于向量,因为它需要元素的单一类型。
有两种方法可以解决此问题。首先是仅对向量的类型进行硬编码。这使代码的通用性降低,但由于您的函数名为int_printf
而不是anything_print
另一种选择是使用std::common_type
来获取元素的通用类型,例如
template <typename ...T>
void int_printf(T ...args)
{
std::vector<std::common_type_t<T...>> vec = {args...};
for(auto& v:vec)
{
std::cout << v << std::endl;
}
}
您也可以使用fold expression并完全跳过向量
template <typename ...T>
void int_printf(T ...args)
{
((std::cout << args << std::endl), ...);
// ^^ ^
// | do this part ^ ^ |
// | for each parameter | |
// start fold expression end fold
}
如果您只需要无限数量的int
,则还可以使用SFINAE将包类型限制为整数,例如
template <typename ...T, std::enable_if_t<std::conjunction_v<std::is_same<T, int>...>, bool> = true>
void int_printf(T ...args)
{
((std::cout << args << std::endl), ...);
}
现在您不能用int
以外的任何函数来调用此函数,但是它可以根据需要任意多。