I am working on a problem that should (since its HW) be solved by variadic templates. My lack of understanding prevents me from solving following error.
The code is:
#include <sstream>
#include <iostream>
#include <string>
#include <vector>
#include <tuple>
template<typename ... TL>
class LazySplitResult
{
public:
LazySplitResult(TL ...pl) :storedParams(pl ...) { }
void doStuff()
{
// invoke method with inside parameters
useStoredTuple(storedParams, std::index_sequence_for<TL...>());
}
template<typename T, typename T1, typename... Targs>
void doInsideLogic(T&& value1, Targs&& ... Fargs)
{
// there is some logic
// for example this
std::stringstream convert("0");
// it works for string,double,int ... other types are not supported
// so exception would be in place
convert >> value1;
}
void doInsideLogic()
{
}
private:
template<std::size_t... Is>
void useStoredTuple(const std::tuple<TL ...>& tuple,std::index_sequence<Is...>) {
wrapInsideLogic(std::get<Is>(tuple) ...);
}
void wrapInsideLogic(TL && ... args)
{
doInsideLogic(args...);
}
std::tuple<TL ...> storedParams;
};
template<typename ...TL>
LazySplitResult<TL ...> getResult(TL && ...pl)
{
return LazySplitResult<TL...>(pl ...);
}
int main()
{
std::string x;
int y;
double z;
// prepares an object
auto lazyResult=getResult(x, '.', '-', y, 'x', z , 'a');
// let it do its thing and set unset variables
lazyResult.doStuff();
std::cout << "x = " << x << ", y = " << y << ", z = " << z << std::endl;
return 0;
}
The error message is here
error C2664: 'void LazySplitResult<std::string &,char,char,int &,char,double &,char>::wrapInsideLogic(std::string &,char &&,char &&,int &,char &&,double &,char &&)': cannot convert argument 2 from 'const char' to 'char &&'
source_file.cpp(40): note: Conversion loses qualifiers
source_file.cpp(18): note: see reference to function template instantiation 'void LazySplitResult<std::string &,char,char,int &,char,double &,char>::useStoredTuple<0,1,2,3,4,5,6>(const std::tuple<std::string &,char,char,int &,char,double &,char> &,std::integer_sequence<_Ty,0,1,2,3,4,5,6>)'
It is copied from rextester here.
The main part of the HW is to parse a formula and save the result in the variables like this:
// declare variables and initialize class with formula
parse(x, '.', '-', y, 'x', z , 'a');
std::cout << "x = " << x << ", y = " << y << ", z = " << z << std::endl;
The code does the same, except it does it in a lazy fashion so the parameters needs to be stored in a tuple for later use.
I tried to implement the same logic, except the laziness, without employing tuples and class with a success. It can be observed here. No error describind conversion errors was raised.
Can you please help me? I am completely lost. The entry method invocation is the same, the variadic template method that process the parameters have the same arguments... Only difference seems to be the tuple and class inbetween.
First, there is a useless template parameter T1
in your doInsideLogic
function template. Remove it.
The parameter of wrapInsideLogic
is not a forwarding reference since TL
is known and is not deduced. Its argument std::get<Is>(tuple)
is of type const TL&
since tuple
is of type const std::tuple<TL...>&
, thus does not match the parameter type TL&&
. To fix this, there are two choices:
Use forwarding reference, i.e.
template <typename... Targs>
void wrapInsideLogic(Targs&&... args)
{
doInsideLogic(std::forward<Targs>(args)...);
}
Use reference to const, i.e.
void wrapInsideLogic(const TL&... args)
{
doInsideLogic(args...);
}