【发布时间】:2013-01-10 16:48:53
【问题描述】:
我刚刚在处理 C++ 项目时遇到了一些意外且令人沮丧的行为。我的实际代码稍微复杂一些,但下面的示例也很好地捕捉到了它:
class Irritating
{
public: Irritating() {}
private: Irritating(const Irritating& other) {}
};
const Irritating singleton; // Works just fine.
const Irritating array[] = {Irritating()}; // Compilation error.
int main()
{
return 0;
}
尝试编译它会产生以下错误(以防万一抛出 GCC 版本):
[holt@Michaela irritating]$ g++ --version
g++ (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2)
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
[holt@Michaela irritating]$ g++ test.cpp
test.cpp:4:11: error: ‘Irritating::Irritating(const Irritating&)’ is private
test.cpp:8:41: error: within this context
[holt@Michaela irritating]$
不幸的是,有问题的对象来自外部库,不受我的控制。我目前的解决方法是使用指针数组;它有效,但感觉有点hackish,并增加了不必要的间接层。有没有更好的方法来做到这一点?
另外:数组是常量和全局的(在实际代码中是类静态的);为什么它没有被初始化到位?这是预期的 C++ 行为,还是 GCC 的错误/怪癖?
更新:安装 Clang 只是为了看看它是否同意 GCC。可悲的是,它做到了:
[holt@Michaela irritating]$ clang test.cpp
test.cpp:8:29: warning: C++98 requires an accessible copy constructor for class 'Irritating' when binding a reference to a temporary; was private
[-Wbind-to-temporary-copy]
const Irritating array[] = {Irritating()};
^
test.cpp:4:11: note: declared private here
private: Irritating(const Irritating& other) {}
^
test.cpp:8:29: error: calling a private constructor of class 'Irritating'
const Irritating array[] = {Irritating()};
^
test.cpp:4:11: note: declared private here
private: Irritating(const Irritating& other) {}
^
1 warning and 1 error generated.
[holt@Michaela irritating]$
【问题讨论】:
-
这就是指定语言的方式。从花括号列表初始化是一个正式的副本,并且需要可以访问复制构造函数(即使它实际上从未被调用过)。
-
@KerrekSB:
even though in practice it may never be called* -
@Non-StopTimeTravel:嘿,你又是别人吗?!停下来!!! :-)
-
@KerrekSB:冬天我没有得到足够的帽子,所以我自己做了一些,我正在连续试戴
标签: c++ g++ initialization copy-constructor