Steve M
Steve M

Reputation: 9794

Passing variadic function template arguments to another function

I am trying to pass my pack to another function, it looks similar to what I'm seeing in tutorials, but not similar enough apparently:

class algorithm
    {
        typedef uint64_t time_type;
    protected:
        std::string name;
        time_type result;

        template <typename... Args>
        void execute(const Args&...);

    public:
        algorithm(std::string name);

        //virtual void prepareTest()=0;
        template <typename TimeT, typename... Args>
        void beginTest(const Args&...);
        void printResult();
        time_type getResult();

    };

    template <typename TimeT, typename... Args>
    void algorithm::beginTest(const Args&... args)
    {
        auto start = chrono::high_resolution_clock::now();

        execute(args...);

        auto duration = chrono::duration_cast<TimeT>
                    (chrono::high_resolution_clock::now() - start);

        result = duration.count();
    }

    template <typename... Args>
    void execute(const Args&... args)
    {
        //nothing here yet
    }

When I instantiate an algorithm and beginTest(), I get a linker error:

const int n = 100000;
const int m = 1000;
algortest::algorithm brutus("brutus");
brutus.beginTest<chrono::milliseconds>(n, m);

undefined symbols for architecture x86_64: "void algortest::algorithm::execute(int const&, int const&)", referenced from: void algortest::algorithm::beginTest >, int, int>(int const&, int const&) in main.o ld: symbol(s) not found for architecture x86_64

What am I am doing wrong? Also, is overriding execute() in a derived class of algorithm going to be possible?

Upvotes: 2

Views: 4982

Answers (1)

Cameron
Cameron

Reputation: 98846

You forgot to prefix the definition of execute with algorithm:: is all :-)

It should read:

template <typename... Args>
void algorithm::execute(const Args&... args)
{
    // ...
}

You might also want to use perfect-forwarding for your arguments instead of forcing them to be passed by reference -- instead of const Args&..., use Args&&... and then std::forward<Args>(args)... when calling the function.

Upvotes: 2

Related Questions