c++ - 编译器在程序代码中提供私有(private)构造函数作为候选

标签 c++ gcc constructor clang

#include <iostream>

using namespace std;

class Test{
private:
    Test(int a, int b=0)
    {
        cout << "private constructor\n";
    }
public:
    Test(int a)
    {
        cout << "public constructor\n";
    }
};

int main()
{
    Test t(1);
}

当我尝试编译代码时 gcc 说:

test.cpp: In function ‘int main()’:
test.cpp:20:10: error: call of overloaded ‘Test(int)’ is ambiguous
  Test t(1);
          ^
test.cpp:12:2: note: candidate: Test::Test(int)
  Test(int a)
  ^
test.cpp:7:2: note: candidate: Test::Test(int, int)
  Test(int a, int b=0)
  ^
test.cpp:5:7: note: candidate: Test::Test(const Test&)
 class Test{
       ^

clang 说:

test.cpp:20:7: error: call to constructor of 'Test' is ambiguous
        Test t(1);
             ^ ~
test.cpp:7:2: note: candidate constructor
        Test(int a, int b=0)
        ^
test.cpp:12:2: note: candidate constructor
        Test(int a)
        ^
test.cpp:5:7: note: candidate is the implicit copy constructor
class Test{
      ^
1 error generated.

产生歧义的原因是什么?由于 Test(int,int) 是私有(private)的,因此不可能在 Test t(1) 中调用它。一个可能的答案是(我最初的想法),它使两个相同的构造函数签名成为可能,即 Test() 可以在私有(private)构造函数中仅用一个 int 调用。但是在程序代码中Test t(1)只对公共(public)构造函数可行,所以它不应该提供私有(private)构造函数作为候选。为什么这么说?

最佳答案

根据标准,由于明确的原因,它是模棱两可的:

[class.access/5]

It should be noted that it is access to members and base classes that is controlled, not their visibility. Names of members are still visible, and implicit conversions to base classes are still considered, when those members and base classes are inaccessible. The interpretation of a given construct is established without regard to access control. If the interpretation established makes use of inaccessible member names or base classes, the construct is ill-formed.

这种可见性意味着编译器必须考虑构造的两个重载,并且它们对您传递的参数同样有效。

由于构造函数是私有(private)的,因此只能在类及其成员的范围内访问,只需删除默认参数值即可。您可以通过其他方式在您的类定义中维护此默认值。例如,通过在类实现文件中引入常量:

int const default_b = 0;

// ...

return Test{a, default_b};

关于c++ - 编译器在程序代码中提供私有(private)构造函数作为候选,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43814242/

相关文章:

c++ - DLL 注入(inject)有效,除非我在 Qt Creator 中编译它

java - 在构造函数中初始化 ArrayList

c++ - Chrono high_resolution_clock 给出不一致的时间?

c - GCC Win32 API 与 ComCtl32 的链接问题

c - "No rule to make target ` install 使用 make install 时出现 `"错误

perl - 配置 OpenDDS

c++ - 将数组从 C++ 构造函数传递给函数

java - 如何编写一个构造函数来阻止在某些条件下创建对象

c++ - unique_ptr C++ 中的 release()

c++ - 通过 C++ 中的 udp 套接字将派生类对象从一个进程发送到另一个进程