我有一个像这样的小代码:
class A {
public:
A() {
std::cout << "ctor\n";
}
A(int i = 5) {
std::cout << "ctor -> v\n";
}
virtual ~A() {
std::cout << "dtor\n";
}
};
int main() {
A a;
}
很明显,由于A
的构造函数不明确,因此无法编译该代码。我想知道是否有通过手动选择要调用的构造函数来消除此代码歧义的方法。我不想传递默认值以消除函数调用的歧义(这是一种明显的方法)。我只想知道是否还有其他方法。
答案 0 :(得分:2)
在不更改构造函数定义的情况下,标准C ++无法消除歧义。
清除歧义的选项是删除默认参数,或向第一个构造函数添加“ dummy”标记参数。
constexpr struct default_tag_t{} default_tag{};
///
A(default_tag_t) {
std::cout << "ctor\n";
}
哪个使得第一个构造函数可以唯一地调用
A a(default_tag);
答案 1 :(得分:1)
我能看到的唯一方法(如果您确实需要两个构造函数)是删除第二个构造函数中参数的默认值,并使'default'构造函数进行调用:>
class A {
public:
A() : A(5) {
std::cout << "ctor\n";
}
A(int i) {
std::cout << "ctor -> v\n";
}
virtual ~A() {
std::cout << "dtor\n";
}
};
但是,对于默认(“空”)实例化,两个构造函数的主体代码都将执行。
答案 2 :(得分:1)
实际上,我认为这是不可能的。我一直想称呼残缺的名称,但无法生成这些残缺的名称。为此,您必须通过添加__declspec(dllexport)
将类公开给二进制接口,然后执行此操作,甚至不再可能编译该类(无论调用任何ctor都是如此):
#include <iostream>
class __declspec(dllexport) A {
public:
A() {
std::cout << "ctor\n";
}
A(int i = 5) {
std::cout << "ctor -> v\n";
}
virtual ~A() {
std::cout << "dtor\n";
}
};
int main() {
// A a;
}
输出原为
1>------ Build started: Project: ConsoleApplicationMangled, Configuration: Debug Win32 ------
1>ConsoleApplicationMangled.cpp
1>e:\temp\ConsoleApplicationMangled\ConsoleApplicationMangled\ConsoleApplicationMangled.cpp(5,30): error C2668: 'A::A': ambiguous call to overloaded function
1>e:\temp\ConsoleApplicationMangled\ConsoleApplicationMangled\ConsoleApplicationMangled.cpp(11,5): message : could be 'A::A(int)'
1>e:\temp\ConsoleApplicationMangled\ConsoleApplicationMangled\ConsoleApplicationMangled.cpp(7,5): message : or 'A::A(void)'
1>e:\temp\ConsoleApplicationMangled\ConsoleApplicationMangled\ConsoleApplicationMangled.cpp(18,2): message : while trying to match the argument list '()'
1>e:\temp\ConsoleApplicationMangled\ConsoleApplicationMangled\ConsoleApplicationMangled.cpp(18,2): message : This diagnostic occurred in the compiler generated function 'void A::__dflt_ctor_closure(void)'
1>Done building project "ConsoleApplicationMangled.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========