-1

I am creating a class that takes an unknown amount of objects and then draws them on the screen.

I'm trying to utilize templates but don't know how they work, and every source I've read so far shows a different way of writing it.

.cpp

// file composite.cpp

#include <SFML/Graphics.hpp>
#include "composite.h"
#include "copy.h"

template<typename arguments> class drawable
composite<arguments>::composite() {
    drawable<arguments> shape;
}

void draw(sf::RenderWindow & window, sf::Vector2f position) {
    for (int i = 0; i < 10; ++i) {
        //if (parts[i] != NULL) {
            // Draw part
            //parts[i].draw();
        //}
    }
}

.hpp

// file composite.hpp

#ifndef _COMPOSITE_HPP
#define _COMPOSITE_HPP

#include <SFML/Graphics.hpp>
#include "drawable.h"
#include "copy.h"

template<typename arguments>
class composite : public drawable {
public:
    composite<arguments>::composite();
    void draw(sf::RenderWindow & window, sf::Vector2f position) {};
private:
    copy *shape1, *shape2, *shape3;
    copy *parts[10];
};

#endif

Right now I'm getting error's like "error C2514: 'composite' : class has no constructors", but I'm pretty sure I've made a constructor for that class.

What am I doing wrong?

nvoigt
  • 75,013
  • 26
  • 93
  • 142
  • 1
    I think you should be getting more errors than that. That constructor definition in `composite.cpp` doesn't look syntactically correct. Also, please edit your question to show the code where the error happens (i.e. where you create a `composite` object) as well as the *complete* and *unedited* build log. – Some programmer dude Sep 14 '15 at 16:43
  • @JoachimPileborg Well yeah, but is the defining of the template actually done properly? – Aydin Biber Sep 14 '15 at 16:46
  • what are you trying to do with `template class drawable composite::composite(){...}`? – jaggedSpire Sep 14 '15 at 16:48
  • @jaggedSpire I want to create a constructor that takes a variable amount of arguments. – Aydin Biber Sep 14 '15 at 16:50
  • the correct syntax for defining a constructor of a variadic templated class is `template myClass::myClass () {...}` but there are many, many problems with your code. For instance, you can't place the implementation of a templated class in a different translation unit from the client code unless you've done some very particular things like declaring the specific versions of the templated class you're using. The use of `class drawable` in that constructor definition is also just wrong, and you're using a non-variadic template for multiple template arguments. – jaggedSpire Sep 14 '15 at 17:04
  • I'd recommend looking through more information on C++ templates before continuing, such as the [C++ SuperFAQ](https://isocpp.org/faq) entries on Templates, a [few](http://en.cppreference.com/w/cpp/language/parameter_pack) [articles](http://en.cppreference.com/w/cpp/language/variadic_arguments) on Variadic Templates (such as the wiki's) and also [Why Can Tempaltes Only Be Implemented In The Header File?](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – jaggedSpire Sep 14 '15 at 17:08
  • @jaggedSpire I don't really know what most of that means. I'm kinda new to c++. I've also read most of the sources that you've linked (save for the stack one) before posting this question. – Aydin Biber Sep 14 '15 at 17:14
  • Then you will benefit from reading the C++ SuperFAQ even more. It answers commonly asked newbie questions about potentially confusing parts of the C++ language. The definition of your function in the .cpp file are the "Implementation" of the template. They can't be there--.cpp files are compiled separately from one another and use header files--.hpp or .h to tell what one another are doing. *Variadic* templates are templates that take a variable number of arguments, and are more advanced, with more intricacies than the more basic templates, which you may want to learn first. – jaggedSpire Sep 14 '15 at 17:19
  • @jaggedSpire Sadly I don't have much of a choice. I NEED a constructor that takes 0..10 arguments and don't have a lot of time to learn properly. – Aydin Biber Sep 14 '15 at 17:21
  • And you're sure you want a *template* that takes variable arguments, knowing the only way you'll be able to refer to two with different arguments in, say, a loop is with their base class via polymorphism? Or do you want different *construction* behavior dependent on the template arguments, but have the different constructors all produce the same class? – jaggedSpire Sep 14 '15 at 17:27
  • 1
    Well, no problem then. You don't have time to learn how to do something, and you need to do it. The conclusion is obvious: you will fail. That's ok (at least at this end). I'd still advise trying to learn how to do it rather than flailing about. The resources linked do try to teach you how to do it. If you don't have time to read over them, that means you don't have time to solve your problem! – Yakk - Adam Nevraumont Sep 14 '15 at 17:27

3 Answers3

0

What am I doing wrong?

I think you've tried to oversimplify the code for something that isn't trivial and you should reset your research.

It's easy to use other people's templates for the exact thing they are designed for (e.g. std::vector). Designing your own templates is more difficult. I'm not sure by the code in this question if you have even done simple templates before. Your code doesn't show understanding of the concept of the use of templates to implement parameterized classes, which is more fundamental than the concept of passing multiple parameters to a constructor.

cardiff space man
  • 1,442
  • 14
  • 31
0

If you want a function that accepts multiple parameters, maybe this can help you:

template <typename... Args>
void function(Args&&... args) {
//Do something with args or forward it.. 
//(std::forward<Args>(args)...);
}

P.D. Maybe you should explain better your question to receive a better answer.

FrameBuffer
  • 757
  • 1
  • 7
  • 26
0

I found the solution to my problem. If I want to have a constructor that takes a variable set of arguments, I should do the following:

cpp

composite::composite(drawable &copy1, drawable &copy2, drawable &copy3){}

hpp

composite::composite(drawable &copy1 = nullptr, drawable &copy2 = nullptr, drawable &copy3 = nullptr)

This way I can make a call to the constructor with 0..3 arguments (in the actual assignment it's 0..10, but I made it smaller here since it's just an example).