0

I'm trying to implement a variadic method but when I try the following code it doesn't compile:

Configurations.h

#ifndef Test_Configurations_h
#define Test_Configurations_h

#include <vector>

class Configuration
{
public:
    Configuration(){}
    int someData;
};


class Configurations
{
public:
    void addConfiguration (Configuration config);

    template<typename... Args>
    void addConfiguration (Configuration first, Args... args);

private:
    std::vector<Configuration> _configs;

};

#endif

Configurations.cpp

#include "Configurations.h"

void Configurations::addConfiguration (Configuration config)
{
    // do something
}

template<typename... Args>
void Configurations::addConfiguration (Configuration first, Args... args)
{
    // Do something
}

main.cpp

#include <iostream>
#include "Configurations.h"


int main(int argc, const char * argv[]) {

    Configuration c1;
    Configuration c2;

    Configurations configurations;

    configurations.addConfiguration(c1, c2);

    return 0;
}

When I try to call the method

addConfiguration (config1, config2)

The compiler give me the following error:

Undefined symbols for architecture x86_64:
  "void Configurations::addConfiguration<Configuration>(Configuration, Configuration)", referenced from:
      _main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I think that I'm not declaring properly the method, but I don't know where is the error.

Thanks in advance!

Joan P.S
  • 1,553
  • 1
  • 16
  • 42
  • You have a link error, do you implement variadic `addConfiguration` in cpp and use it in other translation unit ? – Jarod42 Oct 30 '14 at 15:17
  • Nope, the point is that if I use an easy example it just works, but when I want to add my own class i have this error – Joan P.S Oct 30 '14 at 15:19
  • I think the body of the template function should be `addConfiguration(first); addConfiguration(args);` otherwise all it will do is add the last configuration passed, and ignore all of the others. – cdhowie Oct 30 '14 at 15:20
  • 3
    I'm guessing that the "easy example" wasn't a template, and that the implementation is in a source file, not a header. A template must be usually be implemented in a header, since the definition must be available in every translation unit that needs to instantiate it. – Mike Seymour Oct 30 '14 at 15:25
  • 1
    Works for me. http://ideone.com/fyUabd – R Sahu Oct 30 '14 at 15:26
  • @MikeSeymour Is there a way to accept argument packs *without* templates? – cdhowie Oct 30 '14 at 15:37
  • @cdhowie: Of course not. If the "easy example" was still variadic, then that part of my guess is wrong. – Mike Seymour Oct 30 '14 at 15:40
  • these type of variadic functions are purely compile time phenomenon (as opposed to `va_arg`). you need templates. – Karoly Horvath Oct 30 '14 at 15:43
  • I just edited the question with the full code to reproduce the error – Joan P.S Oct 30 '14 at 15:55
  • How can this be variadic, when the ... is not at the end of the parameter list? – harper Oct 30 '14 at 16:12
  • do you mean this? addConfiguration (Configuration first, Args... args) – Joan P.S Oct 30 '14 at 16:14

1 Answers1

0

The problem is as Mike said: you're declaring the function template in a header but defining it in a source file. Both the declaration and the implementation need to stay in the same translation unit. I've closed this question as a duplicate with a more comprehensive answer.

David G
  • 94,763
  • 41
  • 167
  • 253