ICC отклоняет инициализацию ссылочного элемента шаблона - PullRequest
6 голосов
/ 06 ноября 2019

Пожалуйста, рассмотрите пример ниже. Шаблон класса 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 принимает оба.

...