我有歸結爲允許在派生類
class interface
{
protected:
virtual void write(std::string const &) = 0;
};
和派生類,如
class derived : public interface
{
protected:
void write(std::string const & buf)
{
std::cout << buf << std::endl;
}
};
在我的應用程序的接口,這些對象被傳來傳去的智能指針流運算符,即std::shared_ptr<derived>
。我希望我可以超載<<
運營商,但只能用於我的界面衍生品的智能指針。我嘗試這樣做:
class interface
{
/* ... */
private:
template <typename Derived> friend typename std::enable_if<
std::is_base_of<interface, Derived>::value,
std::shared_ptr<Derived>
>::type & operator<<(std::shared_ptr<Derived> & lhs,
std::string const & rhs)
{
lhs->write(rhs);
return lhs;
}
};
但是當我嘗試std::shared_ptr<derived> sp; sp << "test";
,編譯器會抱怨說virtual void derived::write(const string&) is protected within this context
(this context
是我的朋友的功能)。
有沒有一種方法可以實現這一點,而無需爲每個派生類冗餘寫入流運算符?
爲什麼'write'是'protected'的任何原因?從你發佈的內容來看,它只有副作用,所以沒有理由把它從用戶身上隱藏起來。特別是因爲用戶無論如何都能夠通過ostream插入器觀察所有這些副作用。 – ComicSansMS
由於'write'是虛擬的,並且在運算符體中'lhs'包含可以轉換爲'interface *'的Derived *',所以可以「向上傳播」(不是直接引用shared_ptr引用,而是底層指針):http ://ideone.com/lqZ2o8(但是就像@ user2362671所說的那樣,你可以使用'std :: shared_ptr sp(new derived)'代替) –
@ComicSansMS我想保持公共API儘可能乾淨,並且gx_的解決方案似乎準確地說,還是有沒有解決方案的缺點,我沒有看到? – user2573221