C++ convert string to typename


C++ convert string to typename



So I've found a variety of articles and posts saying that there is no way to convert typename to string but I haven't found one about the opposite. I have a template of a function with specializations:


typename


string


template


template <typename T>
void foo(T sth) {}

template <>
void foo<int>(int sth) {}
...



and I'm reading from a file constructed like this:


int 20
double 12.492
string word



Is there a way to call the correct specialization of foo() depending on the content of the file?


foo()





Templates are compile-time constructs, you cannot instantiate or choose template specializations at runtime
– UnholySheep
Jul 1 at 21:11






if (std::compare(sType)=="string" {...} else if (std::compare(sType)=="int") {...}
– paulsm4
Jul 1 at 21:13



if (std::compare(sType)=="string" {...} else if (std::compare(sType)=="int") {...}





I see, I will edit that one to make sense
– koman900
Jul 1 at 21:14





"there is no way to convert typename to string" Maybe no standard ones, but there are some portable enough ones, like taking the name out of a string returned by typename <typename T> const char *foo() {#ifdef _MSC_VER return __FUNCSIG__; #else return __PRETTY_FUNCTION__;}.
– HolyBlackCat
Jul 1 at 21:26


typename <typename T> const char *foo() {#ifdef _MSC_VER return __FUNCSIG__; #else return __PRETTY_FUNCTION__;}




2 Answers
2



Yes there is, but it requires manual code and that you know all the types that are going to appear in the file. That's because templates are compile time constructs and they cannot be instantiated at runtime.



You can always use the preprocessor or other tricks to try and reduce the boilerplate if you want to.


void callFoo(std::string type, std::any arg) {
if (type == "int")
foo<int>(std::any_cast<int>(arg));
else if (type == "double")
foo<double>(std::any_cast<double>(arg));
else if (type == "string")
foo<std::string>(std::any_cast<std::string>(arg));
}



Of course, this requires that you pass in the correct type (no implicit conversions!). I don't see any way to avoid that.





Thank you for your answer, looks good to me, I'll leave the question open for some other answers though
– koman900
Jul 1 at 21:51





@koman Oh yes please do. I also want to know if there is a cleaner solution than mine :)
– Rakete1111
Jul 1 at 21:51



To be honest, I am not sure about understanding your question. As I interpret it, I believe that you do not need a kind of dispatcher in running time neither to compute a string containing the type name. Simply you write a general template function that calls a special template wrapper that disambiguates the call to foo() according to the type. You require that the specialized foo() receives a second special parameter (the_type<T>) which is used for disambiguating.


foo()


foo()


the_type<T>



Here a full and operating demo:


# include <string>
# include <iostream>

using namespace std;

template<class T> struct the_type { using type = T; };

template <typename T>
void foo(const T par)
{
foo(par, the_type<T>());
}

void foo(int par, the_type<int>)
{
cout << "int " << par << endl;
}

void foo(double par, the_type<double>)
{
cout << "double " << par << endl;
}

void foo(const string & par, the_type<string>)
{
cout << "string " << par << endl;
}

void foo(const char * par, the_type<const char*>)
{
cout << "char* " << par << endl;
}

int main()
{
foo(20);
foo(12.492);
foo("word");
foo(string("word"));
}



whose output is:


int 20
double 12.492
char* word
string word



If you need another specialization, then you simply define it. In some cases, you will have to explicitly to define the specialization as the template parameter.



You could use macro manips for avoiding repetitive things. For example, given that foo() structure is the same, you could encapsulate it in a macro. Something like this:


foo()


# define GENFOO(type_name)
void foo(type_name par, the_type<type_name>)
{
cout << #type_name " " << par << endl;
}

GENFOO(int);
GENFOO(double);
GENFOO(string)



However, I would say that each specialized version of foo() would not be so similar.


foo()






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

How to add background colour in existing image using Swift?

Moria Casán

How to make file upload 'Required' in Contact Form 7?