请考虑以下示例。类模板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;
}
当然,在看到T
的实际参数之前,编译器无法告诉初始化是否有效,或者函数返回的类型是否不合适。因为它也无法确定T
是否将具有这样的功能,或者它是否将完全返回任何内容。
以下解决方法使代码通过:
static_cast
确认所需的类型,如示例。innerOk_
初始化而不是()
。ICC(19.0.1)这么早执行检查并拒绝直接初始化对吗? GCC都接受。
阅读{}
后,似乎ICC尚未解决此this answer。如果我们尝试使用GCC 4.8.5来defect report此代码,但该代码也不包含该修复程序,我们将得到基本上相同的错误: