Windows 7 cygwin 1.7.20 gcc 4.5.3
我的一个类中有一个方法,enqueue(const PTR X,const void * operation),当试图调用它时,实际调用另一个方法,enqueue(bool X)'当原始方法更改为,enqueue(const PTR X)正确调用它。我无法弄清楚我可能做了什么来引发这种行为。代码是可编译的。
/****** SlipDef.h ******/
#ifndef SLIPDEF_H
#define SLIPDEF_H
# include <string>
# include "SlipPointer.h"
using namespace std;
namespace slip {
typedef unsigned char UCHAR;
typedef signed char CHAR;
typedef unsigned short USHORT;
typedef signed short SHORT;
typedef unsigned int UINT;
typedef signed int INT;
typedef unsigned long ULONG;
typedef signed long LONG;
typedef float FLOAT;
typedef double DOUBLE;
typedef SlipPointer * PTR;
typedef SlipPointer * STRING;
} // namespace slip
#endif /* SLIPDEF_H */
/****** SlipHeader.h ******/
#ifndef _SLIPHEADER_H
#define _SLIPHEADER_H
# include <string>
# include "SlipDef.h"
namespace slip {
class SlipHeader {
public:
SlipHeader& enqueue(SlipHeader& X);
SlipHeader& enqueue(bool X);
SlipHeader& enqueue(UCHAR X);
SlipHeader& enqueue(CHAR X);
SlipHeader& enqueue(ULONG X);
SlipHeader& enqueue(LONG X);
SlipHeader& enqueue(DOUBLE X);
SlipHeader& enqueue(const PTR X, const void* operation);
SlipHeader& enqueue(const string& X, bool constFlag = false);
SlipHeader& enqueue(const string* X, bool constFlag = false);
};
};
#endif /* SLIPHEADER_H */
/****** SlipPointer.h ******/
#ifndef SLIPPOINTER_H
#define SLIPPOINTER_H
using namespace std;
namespace slip {
class SlipPointer {
public:
};
} // namespace slip
#endif /* SLIPPOINTER_H */
/****** TheOtherHeader.h ******/
#ifndef _THEOTHERHEADER_H
#define _THEOTHERHEADER_H
# include <string>
# include "SlipDef.h"
namespace slip {
class TheOtherHeader {
public:
TheOtherHeader& enqueue(TheOtherHeader& X);
TheOtherHeader& enqueue(bool X);
TheOtherHeader& enqueue(UCHAR X);
TheOtherHeader& enqueue(CHAR X);
TheOtherHeader& enqueue(ULONG X);
TheOtherHeader& enqueue(LONG X);
TheOtherHeader& enqueue(DOUBLE X);
TheOtherHeader& enqueue(const PTR X);
TheOtherHeader& enqueue(const string& X, bool constFlag = false);
TheOtherHeader& enqueue(const string* X, bool constFlag = false);
};
};
#endif /* _THEOTHERHEADER_H */
/****** main.cpp ******/
# include "SlipHeader.h"
#include "TheOtherHeader.h"
# include <string>
# include <iostream>
using namespace std;
using namespace slip;
int main(int argc, char** argv) {
SlipPointer* ptr = new SlipPointer();
SlipHeader* header = new SlipHeader();
TheOtherHeader* theOtherHeader = new TheOtherHeader();
header->enqueue(ptr);
theOtherHeader->enqueue(ptr);
return 0;
}
/****** SlipHeader.cpp ******/
# include <string>
# include <iostream>
# include "SlipDef.h"
# include "SlipHeader.h"
namespace slip {
static void* ptrOP;
SlipHeader& SlipHeader::enqueue(SlipHeader& X) { cout << "enqueue(SlipHeader& X) wrong answer" << endl; return *new SlipHeader();}
SlipHeader& SlipHeader::enqueue(bool X) { cout << "enqueue(bool X) wrong answer" << endl; return *new SlipHeader();}
SlipHeader& SlipHeader::enqueue(UCHAR X) { cout << "enqueue(UCHAR X) wrong answer" << endl; return *new SlipHeader();}
SlipHeader& SlipHeader::enqueue(CHAR X) { cout << "enqueue(CHAR X) wrong answer" << endl; return *new SlipHeader();}
SlipHeader& SlipHeader::enqueue(ULONG X) { cout << "enqueue(ULONG X) wrong answer" << endl; return *new SlipHeader();}
SlipHeader& SlipHeader::enqueue(LONG X) { cout << "enqueue(LONG X) wrong answer" << endl; return *new SlipHeader();}
SlipHeader& SlipHeader::enqueue(DOUBLE X) { cout << "enqueue(DOUBLE X) wrong answer" << endl; return *new SlipHeader();}
SlipHeader& SlipHeader::enqueue(const PTR X, const void* operation = ptrOP) {
cout << "enqueue(PTR X) right answer" << endl; return *new SlipHeader();
};
SlipHeader& SlipHeader::enqueue(const string& X, bool constFlag) { cout << "enqueue(string& X) wrong answer" << endl; return *new SlipHeader();}
SlipHeader& SlipHeader::enqueue(const string* X, bool constFlag) { cout << "enqueue(string* X) wrong answer" << endl; return *new SlipHeader();}
};
/****** TheOtherHeader.cpp ******/
# include <string>
# include <iostream>
# include "SlipDef.h"
# include "TheOtherHeader.h"
namespace slip {
static void* ptrOP;
TheOtherHeader& TheOtherHeader::enqueue(TheOtherHeader& X) { cout << "enqueue(TheOtherHeader& X) wrong answer" << endl; return *new TheOtherHeader();}
TheOtherHeader& TheOtherHeader::enqueue(bool X) { cout << "enqueue(bool X) wrong answer" << endl; return *new TheOtherHeader();}
TheOtherHeader& TheOtherHeader::enqueue(UCHAR X) { cout << "enqueue(UCHAR X) wrong answer" << endl; return *new TheOtherHeader();}
TheOtherHeader& TheOtherHeader::enqueue(CHAR X) { cout << "enqueue(CHAR X) wrong answer" << endl; return *new TheOtherHeader();}
TheOtherHeader& TheOtherHeader::enqueue(ULONG X) { cout << "enqueue(ULONG X) wrong answer" << endl; return *new TheOtherHeader();}
TheOtherHeader& TheOtherHeader::enqueue(LONG X) { cout << "enqueue(LONG X) wrong answer" << endl; return *new TheOtherHeader();}
TheOtherHeader& TheOtherHeader::enqueue(DOUBLE X) { cout << "enqueue(DOUBLE X) wrong answer" << endl; return *new TheOtherHeader();}
TheOtherHeader& TheOtherHeader::enqueue(const PTR X) {
cout << "enqueue(PTR X) right answer" << endl; return *new TheOtherHeader();
};
TheOtherHeader& TheOtherHeader::enqueue(const string& X, bool constFlag) { cout << "enqueue(string& X) wrong answer" << endl; return *new TheOtherHeader();}
TheOtherHeader& TheOtherHeader::enqueue(const string* X, bool constFlag) { cout << "enqueue(string* X) wrong answer" << endl; return *new TheOtherHeader();}
};
答案 0 :(得分:1)
您有const void* operation
的默认参数。但是,您在实现中设置这些默认参数而不是标题 - 它应该是相反的方式:
// header
void f(int x=5);
// implementation
void f(int x) { }
原因很简单,如果在主代码中调用header->enqueue(ptr)
,编译器只知道标头给出的信息。如果标头不包含默认参数,则编译器不知道此时是否存在默认参数。
答案 1 :(得分:0)
由于您的头文件定义了这个:
SlipHeader& enqueue(const PTR X, const void* operation);
你这样称呼它:
header->enqueue(ptr);
编译器不会将声明视为函数调用的有效匹配(您只传递一个参数,并且不为第二个参数声明默认参数),并选择一个可以使用单个调用的参数争论而不是。 为什么选择 bool
为什么需要更多地挖掘标准。
在函数的实际定义中为第二个参数提供默认参数的事实在编译main()
时对编译器是不可见的,因此不予考虑。您应该将默认参数移动到标题中(事实上,如果您有警告,您可能会根据您现在安排的方式收到警告)。
编辑:正如aschepler在下面指出的那样,bool
版本被调用的原因是它是[const] void *
唯一允许的自动转换。