Пожалуйста, рассмотрите пример ниже. Шаблон класса 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_
. - Используйте
()
-инициализацию вместо {}
.
Is ICC (19.0.1) правильно ли выполнять эту проверку так рано и отказываться от прямой инициализации? GCC принимает оба.