在 class 构造函数中模板和使用 (#define)

Template and using (#define) in class constructor

我已经实现了堆栈 process.this 程序应该与真正的堆栈完全相同 memory.moreover 我正在尝试使用模板并使程序更通用。我在使用 #define DEFAULT_SIZE 10 作为 class 构造函数的参数时遇到问题。

首先,当我将 DEFAULT_SIZE 放入构造函数的原型时,它进行得很顺利:

#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;
}

但是当我将 DEFAULT_SIZE 放入 class 构造函数的大纲定义中时,我得到了这个错误: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;
}

最后是程序的主要内容:

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

我的问题不是关于"Why can templates only be implemented in the header file?"我的问题是我使用DEFAULT_SIZE的地方。

我想,问题在于模板声明的不同:

 stack(int size);

和模板定义:

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

默认值必须在声明部分,如果定义中的方法签名与声明不同(您在定义中添加 DEFAULT_SIZE)编译器不确定您是否编写了相同的构造函数。请注意,当 s 值未提供给构造函数时应用 DEFAULT_SIZE,因此您的定义将用作默认构造函数,但声明是具有一个参数的构造函数。

如果你用 Ideone 编译你的第二个代码片段,它会给你“redeclaration of 'stack::stack(int)' may not have default arguments”(见 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) {

必须在第一个声明中指定默认参数

如果您声明自己的构造函数,默认构造函数将被删除。但是,只要所有参数都具有默认值,您的构造函数将充当默认构造函数。

您的第一部分声明了构造函数参数的正确默认值。你的第二部分没有,你的编译器没有机会使用构造函数作为默认构造函数。

C++ 规范(§8.3.6 pt.4)中提到

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

所以不能在定义中赋默认值。这就是第二种方法不起作用的原因。

虽然第一种方法会起作用,因为它是您可以在定义中省略默认值的所需行为。