我如何做可变参数的可变参数模板
How do I do variadic templates of variadic arguments
问题陈述
我正在尝试传入一个包含此类通用属性的结构
template <typename Value>
struct ColumnValue {
std::string columnName;
Value value;
};
我还想创建一个接受未知数量参数的函数
print(T... args)
这些参数将是具有 1 个或多个的 ColumnValue 对象类型...
我希望打印函数根据“值”的类型执行不同的操作。
想要的结果
222
"hellooooo"
代码
#include <iostream>
template <typename Value>
struct ColumnValue {
std::string columnName;
Value value;
};
template <template<typename> typename ...X, typename ...Y>
void print(std::string firstArg, const X<Y>& ...args) {
for(auto val : {args...}) {
std::cout << val.value << std::endl;
}
}
int main() {
ColumnValue<int> v{
.columnName="hello",
.value=222
};
ColumnValue<std::string> d{
.columnName="hello",
.value="hellooooo"
};
print("", v, d);
return 0;
}
错误信息
: In instantiation of ‘void print(std::string, const X&
...) [with X = {ColumnValue, ColumnValue}; Y = {int,
std::__cxx11::basic_string,
std::allocator >}; std::string =
std::__cxx11::basic_string]’: :28:19: required from
here :12:5: error: unable to deduce
‘std::initializer_list&&’ from ‘{args#0, args#1}’ 12 |
for(auto val : {args...}) {
| ^~~ :12:5: note: deduced conflicting types for parameter ‘auto’ (‘ColumnValue’ and
‘ColumnValue >’)
ColumnValue
是模板这一事实对 print
的签名没有任何影响。我们可以只采用常规参数包,让编译器找出不同的类型。
其次,我们不能遍历参数包。但是我们可以使用 fold-expression.
最终结果看起来像这样
template <typename... T>
void print(std::string firstArg, const T& ...args) {
(std::cout << ... << args.value) << std::endl;
}
如果你想在每个参数之间插入一个换行符,你需要一些帮助。最简单的想法是。
template <typename T>
void print_helper(const T& arg) {
std::cout << arg << '\n';
}
template <typename... T>
void print(std::string firstArg, const T& ...args) {
(print_helper(args.value), ...);
}
问题陈述
我正在尝试传入一个包含此类通用属性的结构
template <typename Value>
struct ColumnValue {
std::string columnName;
Value value;
};
我还想创建一个接受未知数量参数的函数
print(T... args)
这些参数将是具有 1 个或多个的 ColumnValue 对象类型...
我希望打印函数根据“值”的类型执行不同的操作。
想要的结果
222
"hellooooo"
代码
#include <iostream>
template <typename Value>
struct ColumnValue {
std::string columnName;
Value value;
};
template <template<typename> typename ...X, typename ...Y>
void print(std::string firstArg, const X<Y>& ...args) {
for(auto val : {args...}) {
std::cout << val.value << std::endl;
}
}
int main() {
ColumnValue<int> v{
.columnName="hello",
.value=222
};
ColumnValue<std::string> d{
.columnName="hello",
.value="hellooooo"
};
print("", v, d);
return 0;
}
错误信息
: In instantiation of ‘void print(std::string, const X& ...) [with X = {ColumnValue, ColumnValue}; Y = {int, std::__cxx11::basic_string, std::allocator >}; std::string = std::__cxx11::basic_string]’: :28:19: required from here :12:5: error: unable to deduce ‘std::initializer_list&&’ from ‘{args#0, args#1}’ 12 | for(auto val : {args...}) { | ^~~ :12:5: note: deduced conflicting types for parameter ‘auto’ (‘ColumnValue’ and ‘ColumnValue >’)
ColumnValue
是模板这一事实对 print
的签名没有任何影响。我们可以只采用常规参数包,让编译器找出不同的类型。
其次,我们不能遍历参数包。但是我们可以使用 fold-expression.
最终结果看起来像这样
template <typename... T>
void print(std::string firstArg, const T& ...args) {
(std::cout << ... << args.value) << std::endl;
}
如果你想在每个参数之间插入一个换行符,你需要一些帮助。最简单的想法是。
template <typename T>
void print_helper(const T& arg) {
std::cout << arg << '\n';
}
template <typename... T>
void print(std::string firstArg, const T& ...args) {
(print_helper(args.value), ...);
}