Ugo Hed Ugo Hed - 1 month ago 10
C++ Question

Template function C++, that take param U and return T

I am in trouble with Templates, I want to get the content of a file and store it in a String. I'm working with Qt on a generic function which will handle char *, QString and string.

I have a template, which i call with:

std::string test = openStyle("style.css");


I want to get in test the value styleToAdd, which is the content of my file style.css:

EDIT: change const T&openstyle to const T, thanks to Stadium.

template<typename T>
const T openStyle(const T &type)
{
QFile File(QCoreApplication::applicationDirPath() + "/" + type);
File.open(QFile::ReadOnly);
QString styleToAdd = QLatin1String(File.readAll());

return (styleToAdd);
}


But compilation say:

invalid initialisation of reference type "const char (&)[14]" from expression "QString"


I think it is because in the template, the return value is the same as the parameter and not my test variable, but is there a way to be able to return another type (in generic way)

so we can do things like that with the template:

std::string test = openStyle("style.css");
char * test = openStyle("style.css");
QString test = openStyle("style.css");
const char * test = openStyle("style.css");

Answer

It is not possible to automatically determine the return type of a function in the way you tried it.

If you want a template function as you described, the syntax would be like this:

template<typename T, typename U>
const T &openStyle(const U &type)

but you would need to call it like this:

std::string test = openStyle<std::string,const char[]>("style.css");

which is probably not what you want. Besides this you would have to find a way to convert your QString styleToAdd to any type T - so the problem is not solved but just moved to the return type.

Since the filename is always a string, you can simply choose one here and always return a QString and define your function like this:

const QString &openStyle(const std::string &type) 
//choose if you like std::string, QString or char[] here.

While you can not overload the cast operator outside of QString, you could overload the stream operator globally for the needed types:

 operator<< (std::string& left,const QString& right){left = right.toStdString();}
 operator<< (char*, const QString&); //similar conversions here
 operator<< (QString&, const std::string&); //and here

using the provided functions QString::toStdString() and std::string::c_str() and then write:

std::string test << openStyle("style.css");
char * test << openStyle("style.css");
QString test << openStyle("style.css");
const char * test << openStyle("style.css");