4

下面的代码片段是一个游戏,编译器抱怨返回值,所以我想要一些关于如何做这个技巧的反馈,让一个函数根据输入的类型返回两种不同的类型,但不重载

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

3 回答 3

5

如果您想使用模板定义通用行为,但为少数特定类型覆盖该行为,您应该使用模板专业化

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 */
}

您目前错误的原因是您已将返回类型定义为T. 但是您的逻辑已设置为 ifT是 typefloat函数尝试返回 a std::stringstd::string从to可能没有隐式转换T,因此出现错误。

如果您不想重复公共代码,您可以将其提取到一个单独的模板函数中,该函数由上述两个函数调用。

于 2013-05-11T19:48:14.743 回答
1

C++ 是一种强大的静态类型编译语言——你不能有一个返回不同类型的函数。您仅限于单一返回类型。

话虽如此,您可以使用 Boost'svariant或 Qt's QVariant,它们可以封装不同的类型。或者实施针对您的特定需求量身定制的定制变体解决方案。

于 2013-05-11T20:13:18.920 回答
0

关于错误error C2059: syntax error : 'return',这是解决此特定错误的方法:

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

运算符是一个表达式,?:运算符的每个参数都应该是一个表达式。return是一个声明。不是表达式。

作为表达式,?:具有完全单一的类型。但是"never"spawntimesecs是不相关的类型。编译器无法处理。这两个值不属于同一个?:表达式。

您可能可以使用联合,但不建议这样做。

更好的解决方案根本不使用模板,因为您不以任何多态方式使用类型参数:

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();
}
于 2013-05-11T19:38:08.517 回答