c++模板与STL返回类型的组合

C++ template combined with STL return types

本文关键字:返回类型 组合 STL c++      更新时间:2023-10-16

我有一个模板化的类

template <typename T>
class Factors
{
    public:
    Factors(){};
    deque<string> stringsDeck;
    // some methods and variables here
   map <string, string> getNext();
};

getNext方法将作为键的字符串与作为值的stringsDeck中的字符串组合,并返回一个map <string,string>。假设我已经模板化了stringifystring2num函数,我想要有一个方法map<string,Scalar> getNext(),它用于除字符串以外的所有其他类型,将映射的值转换为指定的模板类型T

编译器不允许我重载两个名称相同但返回类型不同的方法,特别是:

map <string, T > getNext()
{
// converts the values of getNext() return map into the specified type T
return convertedMapWithValuesOfTypeT;
}

这种情况下的解决方案是什么?我想保持字符串和其他类型(基本上是数字类型,可以通过词法强制转换从字符串)的方法名称相同

语言不允许函数重载返回类型,因为在大多数情况下,不考虑返回类型函数重载解析。在这种情况下,你真的有三个可能的解决方式:

    最简单的(因此在大多数情况下也是首选的解决方案)是只是给这两个函数取不同的名字:getNextAsMapToType和例如,getNextAsMapToString。或者,你可以将函数声明为模板:<>之前template<typename标签;std::>之前然后,将此函数专门化为std::stringT(和for没有别的)。用户必须指定getNext<std::string>()或者getNext<...>打电话给他想要的人。一般来说,我觉得这个比以前的解决方案,但它可能适用于模板,其中名称应该包含或至少暗示类型的名称。
  • 最后,可以模拟返回的重载键入,如果你不介意一些额外的复杂性。要做到这一点,你仍然必须实现其他解决方案之一,但客户端代码我看不出来。基本上,您的getNext()函数必须返回a带有重载转换函数的代理,类似于:<>之前类代理{因素*我;公众:代理(factors&owner): myOwner(&owner) {}操作符std::map<std::string,>() const{返回直到-> getNextAsMapToString ();}std::string, T>() const{返回直到-> getNextAsMapToType ();}};代理getNext(){返回代理(*this);}之前客户端代码可以直接调用getNext(),这取决于它们做的结果,无论是getNextAsMapToStringgetNextAsMapToType将被调用。

您可以使用[typeid]在getNext中添加运行时检查(http://en.cppreference.com/w/cpp/language/typeid)查看T是否为字符串

类似:

template <typename T>
class Factors
{
    public:
    Factors(){};
    deque<string> stringsDeck;
    // some methods and variables here
    map <string, T> getNext();
    {
        if (typeid(T) == typeid(string))
        {
            // Special handling for strings
        }
        else
        {
            // Do something else for other types
        }
    }
};

编辑

正如fschoenm所建议的,模板专门化可能更好:

template <typename T>
class Factors
{
    public:
    Factors(){};
    // some methods and variables here
    map <string, T> getNext();
};

template <>
class Factors<string>
{
    public:
    Factors(){};
    deque<string> stringsDeck;
    // some methods and variables here
    map <string, string> getNext();
};