resharper — привязка r-значения к ссылке l-value является нестандартным расширением Microsoft C ++

Недавно я работал над проектом и решил установить ReSharper C ++ в Visual Studio. Когда он проанализировал мой код, он выдал кучу новых предупреждений (очевидно, у меня плохие привычки кодирования ..). Один из них, который потребовал у меня некоторое время, чтобы выяснить, был Binding r-value to l-value reference is non-standard Microsoft C++ extension, Я воссоздал предупреждение со следующим кодом:

Type foo(Type t1, Type t2) {
return Type(t1.value & t2.value);
}

Выражение t1.value & t2.value вызывает предупреждение. Я понимаю вторую часть предупреждения, что означает, что мой код компилируется только из-за расширения Microsoft, и другие компиляторы отказываются компилировать его. Я использую перегруженный оператор, который возвращает объект (называется Datum) который Type принимает в качестве параметра конструктора, в качестве ссылки (Type::Type(Datum& dat)).

Немного поиграв, мне удалось убрать предупреждение с помощью рефакторинга кода:

Type bar(Type t1, Type t2) {
Datum datum = t1.value & t2.value;
return Type(datum);
}

Насколько я понимаю, это функционально эквивалентно коду, который сгенерировал предупреждение. То, что я действительно хотел бы знать, есть ли здесь что-то, о чем я должен знать, потому что я довольно озадачен тем, почему одна функция жалуется, а другая нет.

Я думаю, я понял это. У меня уже был напечатан вопрос, поэтому я собираюсь опубликовать его с тем, что нашел, для справки других. У меня нет достаточных знаний, чтобы вдаваться в подробности, поэтому, пожалуйста, не стесняйтесь расширять или исправлять мой ответ, если он не удовлетворителен 🙂

3

Решение

Это один из способов снять предупреждение: переменная именующий, поэтому можно связать напрямую с опорным параметром хитрого конструктора, в то время как результат выражения Rvalue который не может

Лучшее решение состоит в том, чтобы исправить конструктор, чтобы получить его аргумент по значению или константной ссылке:

Type(Datum dat)         // value
Type(Datum const & dat) // constant reference

Теперь вы можете дать аргумент как именующий или Rvalue.

6

Другие решения

Из того, что я вижу, причина такого поведения в том, что Type конструктор принимает ссылка к Datum объект, а не передавать его по значению. Это вызывает предупреждение в Type foo(Type, Type) потому что компилятор не любит брать ссылку на выражения, что было бы связано с семантикой вычисления выражения.

Опять же, пожалуйста, не стесняйтесь уточнять или исправлять мои выводы, так как это просто результат моих экспериментов и умозаключений.

0

По вопросам рекламы [email protected]