![](/img/trans.png)
[英]C++: Correct syntax for friending a template type member of template parameter?
[英]Friending a template parameter
為模板參數提供參與是不可能的,因為標准不允許這樣做。 那我怎么能有效地做同樣的事呢?
我想要的基本上是一種在擁有它的對象之外無法使用的類型。 為什么不是重點,但如果你真的必須知道,我正在嘗試制定一套智能指針來解決共享自有資源的問題。 因此,我想要做的就是這樣,如果它有效:
template < typename T, typename Owner >
struct accessible_member
{
private:
accessible_member() : val(T()) {}
accessible_member(T const& t) : val(t) {}
operator T& () { return val; }
operator T const& () const { return val; }
member_ptr<T> operator & () { return member_ptr<T>(val); }
friend class Owner;
};
因此,一個類不能將該對象保存為成員,除非它聲明自己是所有者,並且如果它足夠愚蠢地按原樣公開它,那么在類之外使用這么愚蠢是不可能的。
你對C ++ 98/03是正確的。 但是C ++ 0x(n3225 11.4 / 3)允許您使用以下語法執行此操作:
friend Owner;
看看你的編譯器是否允許你這樣做。 嘗試啟用C ++ 0x支持。 否則解決方法更加丑陋:
struct Owner
{
typedef Owner self;
};
...
然后根據您的編譯器之一:
friend typename Owner::self;
要么:
friend class Owner::self;
你可以使用它,然后讓所有的所有者繼承自所有者 。
然后,您可以使用Owner類私下包裝accessible_member中使用的方法。
accessible_member是現在擁有者訪問。 Friend不是繼承的,因此您可以提供(包裝)必要的方法,以便繼承所有者的所有類都可以使用accessible_member 。
它是一個2級解決方案,但它保持了封裝級別。
template < typename U >
struct Owner
{
protected:
accessible_member<U> newAccessible_member() { return accessible_member<U>(); }
accessible_member<U> newAccessible_member(U const& u) { return accessible_member<U>(u); }
.....
};
template < typename T >
struct accessible_member
{
private:
accessible_member() : val(T()) {}
accessible_member(T const& t) : val(t) {}
operator T& () { return val; }
operator T const& () const { return val; }
member_ptr<T> operator & () { return member_ptr<T>(val); }
template < typename U> friend class Owner;
};
然后,您可以使用受保護的方法間接地在使用Owner繼承的結構中使用accessible_member:
struct Blah: Owner<int>
{
void Dosomething() {
accessible_member<int> blah= newAccessible_member();
}
};
查看Template Friends的最后一個示例。
7.1.5.3 p2說:
[注意:這意味着,在具有模板類型參數T的類模板中,聲明友元類T; 是不正確的。]
因此,任何允許您使用它的任何解決方案都將符合非標准。
那么簡單地定義一個簡單地從accessible_member繼承的私有嵌套類型呢? 就像是
class Owner
{
template < typename T >
class accessible_member : public ::accessible_member< T > {};
};
當然,這仍然意味着任何人都可以使用原始的accessible_member
類型,因此考慮它可能沒什么用處。
我能看到的唯一解決方法是相當難看並使用CRTP:
template <typename T>
struct CanUseAccessibleMember
{
template <typename T>
static const T& get(const accessible_member<T>& m)
{ return static_cast<const T&>(m); }
// Etc. You can even specialize this class.
};
struct ExampleOwner
: protected CanUseAccessibleMember<ExampleOwner>
{
// Do whatever you want with accessible members here
// but you have to use the get syntax
};
template <typename T, typename Owner>
class accessible_member
{
// Implement members as you did
friend struct CanUseAccessibleMember<Owner>;
};
就我所見,在C ++ 98下,這會有所改變。 它使用g++-4.1 -Wall -Wextra -pedantic -ansi -std=c++98
編譯時沒有任何警告g++-4.1 -Wall -Wextra -pedantic -ansi -std=c++98
只是改變
friend Owner;
至
struct Wrapper { typedef Owner type; };
friend class Wrapper :: type;
(我在Stackoverflow上得到了答案,這個問題已經出現了幾次: 作為朋友的模板參數 )
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.