这个代码,其中有一个const A& a成员B,其中A有一个已删除的拷贝构造函数,不能在GCC 4.8.1中编译,但它在clang 3.4中工作正常:
class A {
public:
A() = default;
A(const A&) = delete;
A& operator=(const A&) = delete;
};
class B{
public:
B(const A& a)
: a{a}
{ }
private:
const A& a;
};
int main()
{
A a{};
B b{a};
}
Run Code Online (Sandbox Code Playgroud)
哪一个编译器是对的?
GCC中的错误是:
prog.cpp: In constructor ‘B::B(const A&)’:
prog.cpp:11:14: error: use of deleted function ‘A::A(const A&)’
: a{a}
^
prog.cpp:4:5: error: declared here
A(const A&) = delete;
^
Run Code Online (Sandbox Code Playgroud)
Ideone:http …
"我们可以初始化一个类的对象,我们没有使用它来定义任何构造函数:
- 成员初始化.
- 复制初始化.
- 默认初始化.
例如:
Run Code Online (Sandbox Code Playgroud)struct Work { string author; string name; int year; }; Work s9 { "Bethoven", "Symphony No. 9 in D minor, Op. 125; Choral", 1824 }; // memberwise initialization Work currently_playing {s9}; // copy initialization Work none {}; // default initialization
C++编程语言第四版.第17.3.1节
例如:
struct Data
{
int mMember1;
float mMember2;
char mMember3;
};
int main()
{
Data aData_1{1,0.3,33};
Data aData_2{aData_1};
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
这必须起作用,虽然我得到的编译器错误与GCC一样多,与Clang一样多.两个编译器中的错误是"无法将数据转换为int".但是,实现复制构造函数时,此错误会消失,或者不使用圆括号语法实现它.问题是有点愚蠢,并改变圆形括号的卷曲问题得到解决.但为什么TC++ PL的规则没有被遵循?,是一个编译器问题还是我误解了什么?提前致谢.
请考虑以下示例。类模板Sample尝试使用模板参数的成员函数初始化引用成员,并期望该成员函数返回适当的引用。
class Inner
{
public:
Inner() : x_{1}
{
}
private:
int x_;
};
class Outer
{
public:
Inner& GetInner()
{
return inner_;
}
private:
Inner inner_;
};
template<typename T>
class Sample
{
public:
Sample(T& outer) :
innerOk_{static_cast<Inner&>(outer.GetInner())},
innerFail_{outer.GetInner()} // ICC fails with "error: initial value of reference to non-const must be an lvalue"
{
}
private:
Inner& innerOk_;
Inner& innerFail_;
};
int main(int argc, char* argv[])
{
Outer outer;
Sample<Outer> s{outer};
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当然,在看到的实际参数之前T,编译器无法告诉初始化是否有效,或者函数返回的类型是否不合适。因为它也无法确定是否 …