Const-correct accessor to vector of pointers without transfer of ownership in abstract interface
<p>I'm designing a library from scratch and want to get the public API as <em>good</em> as possible. I want the compiler to yell at me for misuse. Therefore, I've imposed the following rules on myself:</p>

<ol>
<li><p><strong>true (i.e. deep and complete) const correctness throughout the whole library</strong></p>

<p>All <em>things</em> (local variables, member variables, member functions), which are not expected to change are declared <code>const</code>. That constness should propagate to all nested members and types.</p></li>
<li><p><strong>explicit and expressive ownership</strong></p>

<p>In line with the C++ Core Guidelines I define that as (<em>iff</em> in the mathematical sense of <em>if and only if</em>):</p>

<ol>
<li>function arguments are <code>unique_ptr&lt;T&gt;</code> or <code>T&amp;&amp;</code> <em>iff</em> the function is consuming it (i.e. taking ownership)</li>
<li>function arguments are <code>shared_ptr&lt;const T&gt;</code> or <code>T const&amp;</code> <em>iff</em> the function is only reading it</li>
<li>function arguments are <code>shared_ptr&lt;T&gt;</code> or <code>T&amp;</code> <em>iff</em> the function is modifying it without taking ownership</li>
<li>return values are <code>unique_ptr&lt;T&gt;</code> or <code>T</code> <em>iff</em> the function transfers ownership to the caller</li>
<li>return values are <code>shared_ptr&lt;const T&gt;</code> or <code>T const&amp;</code> <em>iff</em> the caller should only read it (though the caller can construct a copy of it - given <code>T</code> is copyable)</li>
<li>no functions should return <code>shared_ptr&lt;T&gt;</code>, <code>T&amp;</code> or <code>T*</code> (as it would allow for uncontrollable side effects, which I try to avoid by design)</li>
</ol></li>
<li><p><strong>hidden implementation details</strong></p>

<p>For now I'm going with abstract interfaces with factories returning the implementation as a <code>unique_ptr&lt;Interface&gt;</code>. Though, I'm open for alternative patterns which solve my problem described below.</p></li>
</ol>

<p>I don't care about virtual table lookups and want to avoid dynamic casts by all means (I see them as a code smell).</p>

<hr>

<p>Now, given two classes <code>A</code> and <code>B</code>, where <code>B</code> owns a variable number of <code>A</code>s. As well we've the <code>B</code>-implementation <code>BImpl</code> (implementation of <code>A</code> is probably not of use here):</p>

<pre class="lang-cpp prettyprint-override"><code>class A
{};

class B {
 public:
  virtual ~B() = default;
  virtual void addA(std::unique_ptr&lt;A&gt; aObj) = 0;
  virtual ??? aObjs() const = 0;
};

class BImpl : public B {
 public:
  virtual ~BImpl() = default;
  void addA(std::unique_ptr&lt;A&gt; aObj) override;
  ??? aObjs() const override;

 private:
  std::vector&lt;unique_ptr&lt;A&gt;&gt; aObjs_;
};
</code></pre>

<p>I'm stuck with the return value of <code>B</code>s getter to the vector of <code>A</code>s: <code>aObjs()</code>.<br>
It should provide the list of <code>A</code>s as read-only values without transfer of ownership (rule 2.5. above with const correctness) and still provide the caller easy access to all <code>A</code>s, e.g. for use in range-based <code>for</code> or standard algorithms such as <code>std::find</code>.</p>

<p>I came up with the following options for those <code>???</code>:</p>

<ol>
<li><p><code>std::vector&lt;std::shared_ptr&lt;const A&gt;&gt; const&amp;</code></p>

<p>I would have to construct a new vector each time I call <code>aObjs()</code> (I could cache it in <code>BImpl</code>). That feels not only inefficient and needlessly complex, but seems also very suboptimal.</p></li>
<li><p>Replace <code>aObjs()</code> by a pair of functions (<code>aObjsBegin()</code> and <code>aObjsEnd()</code>) forwarding the constant iterator of <code>BImpl::aObjs_</code>.</p>

<p>Wait. I would need to make that <code>unique_ptr&lt;A&gt;::const_iterator</code> a <code>unique_ptr&lt;const A&gt;::const_iterator</code> to get my beloved const correctness. Again nasty casts or intermediate objects. And the user couldn't use it easily in range-based <code>for</code>.</p></li>
</ol>

<p>What obvious solution am I missing?</p>

<hr>

<p><em>Edit</em>:</p>

<ul>
<li><p><code>B</code> should always be able to modify the <code>A</code>s it is holding, thus declaring <code>aObjs_</code> as <code>vector&lt;std::unique_ptr&lt;const A&gt;&gt;</code> is not an option.</p></li>
<li><p>Let <code>B</code> adhere to the iterator concept to iterate over the <code>A</code>s, is neither an option as <code>B</code> will hold a list of <code>C</code>s and a specific <code>D</code> (or none).</p></li>
</ul>