使用没有模板参数的模板化函数

时间:2013-10-31 10:36:57

标签: c++ function templates

我正在使用以下代码从文件加载对象(A,B和C,它们是Object的子类)。我的编译问题来自loadObjFromLine

load.h:611:33: erreur: there are no arguments to ‘loadObjFromLine’ that depend on a template parameter, so a declaration of ‘loadObjFromLine’ must be available [-fpermissive]
load.h:611:33: note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)

当我使用pObj = loadObjFromLine<T>(line);时,我得到了

load.h: In function ‘bool loadObjects(const string&, Object<T>*&)’:
load.h:611:13: erreur: ‘loadObjFromLine’ was not declared in this scope
load.h:611:30: erreur: expected primary-expression before ‘>’ token

修改 我知道我可以使用loadObjFromLine<double>但我希望类型T与loadObject(Object *&amp;)中使用的相同。也许这不是正确的做法..

有什么想法吗?

template<typename T>
Object<T>* loadObjFromLine(const std::string& line)
{
    std::stringstream lineStream(line);
    int objType(-1);
    lineStream >> objType;

    Object<T> *pObj = NULL;

    if (objType == 0)
    {
        A<T> *pO = new A<T>;
        if (lineStream >> *pO)
            pObj = pO;
    }
    else if (objType == 1)
    {
        B<T> *pO = new B<T>;
        if (lineStream >> *pO)
            pObj = pO;
    }
    else if (objType == 2)
    {
        C<T> *pO = new C<T>;
        if (lineStream >> *pO)
            pObj = pO;
    }

    return pObj;
}

template <typename T>
bool loadObjects(   const std::string &filename, Object<T>*& pObj)
{
    std::ifstream fileStream(filename.c_str());
    if (fileStream.good())
    {
        std::string line;
        int objType;

        // Loading boundary.
        while(std::getline(fileStream, line))
        {
            pObj = loadObjFromLine(line);
//          pObj = loadObjFromLine<T>(line);
            if (!pObj)
                return false;
        }
        fileStream.close();
        return true;
    }
    return false;
}

2 个答案:

答案 0 :(得分:0)

这样做:

LoadObjFromLine<Type>(line);

如您所见,有一个字符串参数和一个模板参数:

template <class T>
Obj<T> * LoadObjFromLine(std::string const & line);

您无法推断出参数。为了推导出参数,签名应该是这样的(注意我也将返回类型更改为void)。

template <class Obj>
void LoadObjFromLine(std::string const & line, Obj * obj);

这样你可以做类似的事情:

Obj<MyType> * obj;
LoadObjFromLine(line, obj);

将推断出obj。

在您的情况下,没有参数传递给函数以推导T模板参数。

编辑:如下所述,LoadObjFromLine的首选签名将是您的程序中使用的签名,而不是使用void作为返回类型的签名。 带有void签名的示例仅用于说明何时可以推导出模板参数与无法推断出模板参数的时间

答案 1 :(得分:0)

您需要指定应明确实例化的类型loadObjFromLine,例如:loadObjFromLine<T>("hgjghgj")

在这种情况下,编译器的错误消息非常有用:编译器无法推断它应该实例化函数的类型(因为它不依赖于函数的参数),所以你需要明确它。