Problem Statement
I'm trying to pass in a struct that contains a generic attribute like such
template <typename Value>
struct ColumnValue {
std::string columnName;
Value value;
};
I'd also like to create a function that accepts an unknown number of parameters as such
print(T... args)
These args will be of the type ColumnValue objects with 1 or more...
I'd like the print function to do different things depending on what type "Value" is.
Desired Result
222
"hellooooo"
Code
#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;
}
Error Message
: 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 >’)
CodePudding user response:
The fact that ColumnValue
is a template doesn't make any difference for the signature of print
. We can just take a regular parameter pack and let the compiler figure out the different types.
Secondly we can't loop over a parameter pack. We can however use a fold-expression.
The end result would look something like this
template <typename... T>
void print(std::string firstArg, const T& ...args) {
(std::cout << ... << args.value) << std::endl;
}
If you want to insert a newline between each argument, you would need some kind of helper for that. The simplest idea would be.
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), ...);
}