user2287453
user2287453

Reputation: 149

Using templated function without template parameter

I'm using the following code to load objects (A, B and C which are subclasses of Object) from file. The compilation issue I have is from 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)

And when I use pObj = loadObjFromLine<T>(line); , I get

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

EDIT I know I could use loadObjFromLine<double> but I'd like the type T to be the same used in loadObject(Object*&). Maybe it's not the right approach..

Any idea ?

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;
}

Upvotes: 0

Views: 433

Answers (2)

Germ&#225;n Diago
Germ&#225;n Diago

Reputation: 7663

Do this:

LoadObjFromLine<Type>(line);

As you can see, there is a string parameter and a template parameter:

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

You cannot deduce the parameter. In order for the parameter to be deduced, the signature should be something like this (note I change the return type to void also).

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

This way you could do something like:

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

And obj would be deduced.

In your case there is no argument to pass to function in order to deduce T template parameter.

EDIT: As commented below, the preferred signature for LoadObjFromLine would be the one used in your program, and not the one using void as the return type. The example with void signature was just for the purpose of illustrating when a template parameter can be deduced vs when a template parameter cannot be deduced.

Upvotes: 0

piokuc
piokuc

Reputation: 26164

You need to specify the type loadObjFromLine should be instantiated with explicitly, for example: loadObjFromLine<T>("hgjghgj").

The compiler's error message is quite useful in this case: the compiler cannot deduce the type it should instantiate your function with (as it doesn't depend on function's parameters), so you need to be explicit about it.

Upvotes: 1

Related Questions