0

I have a specific question that I can't really find an answer to in all the questions regarding template member functions. I want to write a function that gets me some data and return it as a vector of a specific type.

I have the following:

#include <vector>

class testClass
{
public:
    template <typename T> std::vector<T> getData(int column);
};


template <typename T> std::vector<T> testClass::getData(int column){
    std::vector<T> returnData;
    return returnData;
}

and to call the function:

int main()
{   
    testClass t;
    std::vector<int> data = t.getData(0);
    return 0;
}

When compiling this I get the error:

../templateTest/main.cpp:9:31: error: no matching member function for call to 'getData'
    std::vector<int> data = t.getData(0);
                            ~~^~~~~~~
../templateTest/testclass.h:8:42: note: candidate template ignored: couldn't infer template argument 'T'
    template <typename T> std::vector<T> getData(int column);
                                         ^

Ok, so it can't get the template argument from the template in the return type. To fix this I try to include the template argument in the call:

int main()
{   
    testClass t;
    std::vector<int> data = t.getData<int>(0);
    return 0;
}

This compiles but gives me a linker error:

Undefined symbols for architecture x86_64:
  "std::__1::vector<int, std::__1::allocator<int> > testClass::getData<int>(int)", referenced from:
      _main in main.o

One final try is to include the template argument also in the function definition:

class testClass
{
public:
    template <typename T> std::vector<T> getData<T>(int column);
};

This however doesn't compile... :

../templateTest/testclass.h:8:42: error: member 'getData' declared as a template
    template <typename T> std::vector<T> getData<T>(int column);

Is it possible what I try to do?

Thanks!!

----------EDIT---------

Putting the implementation in the header does work. If you however prefer to have your implementation in the .cpp. Add the the last line for each implementation that you plan on using.

#include "testclass.h"

template <typename T> std::vector<T> testClass::getData(int column){
    std::vector<T> returnData;
    return returnData;
}

template std::vector<int> testClass::getData(int column);
8
  • Click works well Commented Aug 23, 2017 at 9:34
  • Cannot reproduce. Commented Aug 23, 2017 at 9:35
  • Yes, I also just tested with GCC 7. Commented Aug 23, 2017 at 9:35
  • Side note: Are you sure that it's the function, not the class that should be templated? Commented Aug 23, 2017 at 9:36
  • Hmm... I use clang. And yes, it's the function. In the real implementation I need that function to return whatever I need. The actual class represents a whole bunch of different types of data. Commented Aug 23, 2017 at 9:37

2 Answers 2

1

Most likely your just defined your function template in a .cpp file instead of .h. That is why on t.getData<int>(0) you get a linker error. If that is the case, read this post.

Sign up to request clarification or add additional context in comments.

Comments

0

I just ran the following program and it compiles fine.

#include <vector>

class testClass
{
public:
    template <typename T> std::vector<T> getData(int column);
};


template <typename T> std::vector<T> testClass::getData(int column){
    std::vector<T> returnData;
    return returnData;
}

int main()
{
    testClass t;
    std::vector<int> data = t.getData<int>(0);
    return 0;
}

With templates you should not be using a separate cpp file for the functions. Make sure you put the definition in the header file. This is necessary because any type can be passed in the template and the compiler will need to make a new version of the function for each different type. When dealing with templates I often just define my function inside the class.

class testClass
{
public:
    template <typename T> std::vector<T> getData(int column){
        std::vector<T> returnData;
        return returnData;
    }
};

3 Comments

Sweet, thanks!! I indeed define the function in a separate cpp file.
Just as some extra info. If you do want to put your code in the cpp, you can add the specific implementation to your cpp file. It will then link. So in case of using let's say and int and a double add:
template std::vector<int> testClass::getData(int column); template std::vector<double> testClass::getData(int column);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.