1

I've implemented stack process.this program is supposed to work exactly the same as a real stack memory.moreover i'm trying to use Template and make the the program more generic. I've got a problem in using #define DEFAULT_SIZE 10 as the argument of class constructor.

First of all when i put DEFAULT_SIZE in the prototype of the constructor it goes smoothly:

#define DEFAULT_SIZE 10

template<typename T>
class stack {
public:
   stack(int size=DEFAULT_SIZE);
private:
   T *elements;
   int size;
   int count;
};

template<typename T>
stack<T>::stack(int s) {
   cout << "--constructor called\n";
   size = s;
   elements = new T[size];
   count = 0;
}

But when I just put DEFAULT_SIZE in outline definition of the class constructor i get this error: no appropriate default constructor available

#define DEFAULT_SIZE 10

template<typename T>
class stack {
public:
   stack(int size);
private:
   T *elements;
   int size;
   int count;
};

template<typename T>
stack<T>::stack(int s=DEFAULT_SIZE) {
   cout << "--constructor called\n";
   size = s;
   elements = new T[size];
   count = 0;
}

Finally the main of the program:

int main() {
   stack<int> u;
   u.push(4);
}

My question is not about "Why can templates only be implemented in the header file?" My problem is the place where I use DEFAULT_SIZE.

M.M
  • 138,810
  • 21
  • 208
  • 365
Kasra
  • 63
  • 8
  • Please fix your code block using code captions. – vincent May 25 '16 at 05:10
  • thank you a lot for reminding.is the question clear??? – Kasra May 25 '16 at 05:15
  • Where did you get the "no appropriate default constructor available" error in this code? – Andreas H. May 25 '16 at 05:18
  • I get the error in the line that i write (stack u;) – Kasra May 25 '16 at 05:24
  • Possible duplicate of [Why can templates only be implemented in the header file?](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) Basically, put the implementation in the header file, rather than creating a separate implementation file. – vincent May 25 '16 at 05:46
  • would you mind explain more...i didn't get it – Kasra May 25 '16 at 05:56
  • Please quote any specific issues you are having, such as compiler messages. – n. m. could be an AI May 25 '16 at 06:17
  • of course.but this is the only error that i get... – Kasra May 25 '16 at 07:47
  • @vincent that is not related to this question – M.M May 25 '16 at 22:26
  • By the way, it is not a good idea to use `#define` because then you pollute the code of anybody else who includes your header. Preferably just put `10` as the default argument; but you could either use `enum : int { DEFAULT_SIZE = 10 };`, or `static const int DEFAULT_SIZE = 10;` -- and preferably inside the class definition so that it is scoped to that class. – M.M May 25 '16 at 22:29
  • what a good idea.thank you.i think enum would be graet for it. – Kasra May 26 '16 at 04:32

3 Answers3

2

I suppose, the problem is just in difference of template declaration:

 stack(int size);

and template definition:

stack<T>::stack(int s=DEFAULT_SIZE) {
   ...
}

Default values must be in declaration part, and if method signature in definition is different from declaration (you add DEFAULT_SIZE in definition) compiler is not sure you write the same constructor. Note, DEFAULT_SIZE is applied when s value not given to constructor, so you definition will work as default constructor, but declaration is constructor with one parameter.

VolAnd
  • 6,367
  • 3
  • 25
  • 43
1

If you compile your second code snippet with Ideone for example it gives you "redeclaration of 'stack::stack(int)' may not have default arguments" (see http://ideone.com/UKIx2r).

prog.cpp:16:35: error: redeclaration of 'stack<T>::stack(int)' may not have default arguments [-fpermissive]
 stack<T>::stack(int s=DEFAULT_SIZE) {

Default parameters have to be specified in the first declaration

If you declare your own constructors the default constructor will be deleted. However, your constructor will act as a default constructor as long as all parameters have default values.

Your first part declares a correct default value for the constructors parameter. Your second part does not and your compiler has no chance to use the constructor as a default constructor.

Andreas H.
  • 1,757
  • 12
  • 24
  • I get the error in the line that i write (stack u;) – Kasra May 25 '16 at 05:19
  • I added my answer to explain what happened – Andreas H. May 25 '16 at 05:25
  • thank you a lot..I've been searching for an answer for years . – Kasra May 25 '16 at 05:33
  • Hi @Kasra if this or any answer has solved your question please consider accepting it by clicking the check-mark. This indicates to the wider community that you've found a solution and gives some reputation to both the answerer and yourself. There is no obligation to do this. (comment stolen from Ben at http://meta.stackoverflow.com/a/251298/6172310) – Andreas H. May 25 '16 at 14:04
  • 1
    note: this rule only applies to templates. Non-template functions may have default arguments added in redeclarations. – M.M May 25 '16 at 22:25
1

It is mentioned in C++ specs(§8.3.6 pt.4) that

For non-template functions, default arguments can be added in later declarations of a function in the same scope.

So you can't assign the default value in the definition. That is the reason for not working of second approach.

While first approach will work as it is a desired behavior that you can omit the default values in the definition.

The Philomath
  • 954
  • 9
  • 15
  • thank you a lot.i get it.but i don't know what dose non-template function is?? would it be alright if you explain it??? – Kasra May 25 '16 at 05:22
  • A normal class member function which is not a template function. For more info please refer this post [link](http://stackoverflow.com/questions/6805507/default-constructor-defined-with-default-arguments-outside-the-class-definition) – The Philomath May 25 '16 at 05:26