Return multiple types

The following code fragment is a game, the compiler complains about the returned values, so I would like to get some feedback on how to otherwise do this trick, so that the function returns two different types based on the entered type, but without overloading

template <typename T> T GetTimeDead(uint64 Guid) { bool stringOutput; if(typeid(T) == typeid(float)) stringOutput = false; else stringOutput = true; bool found = false; for(map<uint32, TrackInfo>::iterator itr = dieTracker.begin(); itr != dieTracker.end(); ++itr) { if(itr->second.GUID == Guid) { found = true; break; } } if(!found) stringOutput ? return "never" : return sObjectMgr->FindCreature(Guid)->GetCreatureData()->spawntimesecs; if(!stringOutput) return dieTracker.find(Guid)->second.seconds; float seconds = dieTracker.find(Guid)->second.seconds; uint64 secs = seconds % 60; uint64 minutes = seconds % 3600 / 60; uint64 hours = seconds % 86400 / 3600; uint64 days = seconds / 86400; ostringstream ss; if(days) days != 1 ? ss << days << " Days " : ss << days << " Day "; if(hours) hours != 1 ? ss << hours << " Hours" : ss << hours << " Hour"; if(minutes) minutes != 1 ? ss << minutes << " Minutes " : ss << minutes << " Minutes "; if(secs || (!days && !hours && !minutes)) secs != 1 ? ss << secs << " Seconds " : ss << secs << " Second "; ss << "ago"; return ss.str(); } 
+4
source share
3 answers

If you want to define general behavior with a pattern, but override this behavior for several specific types, you should use a specialized specialization .

 template<typename T> std::string GetTimeDead(uint64 Guid) { /* code to implement your version that returns std::string */ } template<> float GetTimeDead<float>(uint64 Guid) { /* code to implement your version that returns float */ } 

The reason for your error at the moment is that you have defined the return type as T But your logic is configured so that if T is of type float , the function tries to return a std::string . There is probably no hidden drop from std::string to T , hence the error.

If you do not want to repeat the common code, you can pull it into a separate template function, which is called by the two above.

+5
source

C ++ is a strong and statically typed compiled language - you cannot have a function that returns different types. You are limited to one type of return.

In doing so, you can use the Boost variant or Qt QVariant , which can encapsulate different types. Or implement a customized solution that meets your specific needs.

+1
source

Regarding error error C2059: syntax error : 'return' , this is the way to fix this specific error:

 return stringOutput ? "never" : sObjectMgr->FindCreature(Guid)->GetCreatureData()->spawntimesecs; 

The ?: Operator is an expression, and each argument to the operator must be an expression. return is a statement. not an expression.

As an expression, ?: Has exactly one type. but "never" and spawntimesecs are unrelated types. The compiler cannot handle this. these two values ​​are not included in the same expression ?: .

You may be able to use a join, but this is not recommended.

A better solution would not use a template at all, since you are not using a type parameter in any polymorphic way:

 float GetTimeDeadFloat(uint64 Guid) { return find(Guid) ? dieTracker.find(Guid)->second.seconds : sObjectMgr->FindCreature(Guid)->GetCreatureData()->spawntimesecs; } string GetTimeDeadString(uint64 Guid) { return find(Guid) ? timeToString(dieTracker.find(Guid)->second.seconds) : "never"; } bool find(uint64 Guid) { for(map<uint32, TrackInfo>::iterator itr = dieTracker.begin(); itr != dieTracker.end(); ++itr) { if(itr->second.GUID == Guid) return true; } return false; } string timeToString(float seconds) { string res = timeToString(seconds % 3600 / 60, "Minutes"); res += timeToString(seconds % 86400 / 3600, "Hour"); res += timeToString(seconds / 86400, "Day"); if (secs || res.length() == 0) res += numToString(seconds % 60, "Second"); res += "ago"; return res; } string numToString(uint64 num, string type) { ostringstream ss; if (num) ss << num << " " << type << (num != 1) ? "s" : "" << " "; return ss.str(); } 
0
source

Source: https://habr.com/ru/post/1480282/


All Articles