Что, если вы изменили свой интерфейс, чтобы расширить IEnumerable, чтобы вы могли перечислять объект и редактировать данные через свойство класса.
public interface ISomeData : IEnumerable<string>
{
IEnumerable<string> Data { get; }
}
public class MyData : ISomeData
{
private List<string> m_MyData = new List<string>();
public List<string> Data { get { return m_MyData; }
public IEnumerator<string> GetEnumerator()
{
return Data;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Есть различия. Использование скобок позволит устранить оптимизацию возвращаемого значения .
Если, например, a
и / или b
были объектами с перегруженными всеми подходящими операторами, то использование скобок может привести к дополнительным затратам на копирование значения объекта.
Для простых старых данных нет никакой разницы, в зависимости от мерзости C ++ 11
decltype(auto) ub_server() { int a; return (a);}
, которая фактически дает вам висячую ссылку .
В заключение: не используйте заключенные в скобки, если вы не хотите, чтобы некоторые из вышеуказанного поведения, и, возможно, только тогда, с комментарием поддержки.
Неаккуратная речь x
- это то же самое, что и (x)
(см. этот ответ для ответа «строгая речь»). Добавление скобок вокруг полного выражения ничего не меняет в отношении приоритета оператора .
PS: это оказывает неясное влияние на оптимизацию возвращаемого значения (подробнее см. в этом ответе ). Хотя это определенно не влияет на возвращаемое значение.
Есть ли какая-либо разница между вычислением выражений между двумя приведенными ниже операторами возврата на основе дополнительных скобок?
blockquote>Нет; круглые скобки полностью излишни в этом случае .
Выражение
expr
на самом деле не совпадает с выражением(expr)
, и вы можете наблюдать это с помощьюreturn
, потому что исключение копирования / перемещения запрещено в последнем случае:#include <iostream> struct T { T() { std::cout << "T()\n"; } T(const T&) { std::cout << "T(const T&)\n"; } T(T&&) { std::cout << "T(T&&)\n"; } ~T() { std::cout << "~T()\n"; } }; T foo() { T t; return t; } T bar() { T t; return (t); } int main() { std::cout << "Test 1\n------\n"; foo(); std::cout << '\n'; std::cout << "Test 2\n------\n"; bar(); }
Вывод:
Test 1 ------ T() ~T() Test 2 ------ T() T(T&&) ~T() ~T()
( live demo )
Вероятно, вы можете наблюдать тот же результат до C ++ 17, потому что компиляторы всегда пытались оптимизировать возврат ценности. Даже в вашем стандарте C ++ 98 вы, вероятно, можете заметить, что конструктор копирования не вызывается в первом случае.
Но, эй, ничего из этого не имеет отношения к простому арифметическому выражению.