Можно ли создавать дополнительные ссылки в новом C ++ 11? - PullRequest
2 голосов
/ 29 ноября 2011

Учитывая новый стандарт C ++ 11 и введенную в него семантику перемещения, возможно ли создать значения по умолчанию для ссылок на конструкторы? Здесь Значение по умолчанию для параметра при передаче по ссылке в C ++ , сказано, что нет, но, возможно, новый стандарт допускает некоторую хитрость.

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

class A {
   B& b;
   public:
       A(B & b = B()){} // This does not work
}

и при тестировании я хочу

BMock bMock;
A a(bMock);
bMock.getStatistics();

Есть идеи?

Ответы [ 3 ]

4 голосов
/ 29 ноября 2011

Как насчет этого:

class Foo
{
  B default_B;

public:

  std::reference_wrapper<B> b;

  Foo() : b(std::ref(default_B)) { }

  Foo(B & br) b(std::ref(br)) { }
};

Вот альтернативная идея, которая может быть легче, за счет динамического распределения в случае по умолчанию:

#include <memory>

class Foo
{
  std::unique_ptr<B> pB;

public:

  std::reference_wrapper<B> b;

  Foo() : pb(new B), b(std::ref(*pb)) { }

  Foo(B & br) pb(), b(std::ref(br)) { }
};
1 голос
/ 29 ноября 2011

Да, выражение инициализатора по умолчанию является временным объектом, и оно будет привязано к ссылке rvalue. Однако вам необходимо пропустить временные объекты через std::move, чтобы получить их для привязки к ссылке.

Обычно передача чего-либо через std::move указывает, что оно будет уничтожено вызываемой функцией. Стандарт заходит так далеко, что называет результат std::move «истекающим значением»; хотя для его истечения не существует реальной семантической необходимости, это довольно сильное соглашение.

Итак, вы можете сделать это, но будьте осторожны.

Если присмотреться к вашему примеру, вы хотите сохранить ссылку на b внутри a, что означает, что некуда постоянно сохранять предложенное значение по умолчанию, если не использовался аргумент. Вы бы сохранили ссылку на уничтоженный временный. Так что, к сожалению, я не могу по-настоящему адаптировать ваш пример ...

0 голосов
/ 04 декабря 2011

Просто идея, что по этому поводу:

class A 
{
    std::shared_ptr<B> m_b;

public:
    A() : m_b(new B) {}
    A(B& b) : m_b(&b, [](B*){}) {}
};

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...