簡體   English   中英

為模板參數提供幫助

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM