不可能与模板参数相关,因为标准不允许它。那我怎么能有效地做同样的事呢?
我想要的基本上是一种在拥有它的对象之外无法使用的类型。为什么不是重点,但如果你真的必须知道,我正在尝试制定一套智能指针来解决共享自有资源的问题。因此,我想要做的就是这样,如果它有效:
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;
};
因此,一个类不能将这个对象保存为成员,除非它声明自己是所有者,如果它足够愚蠢地暴露它,那么就不可能在类之外使用这么愚蠢。
答案 0 :(得分:5)
你对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;
答案 1 :(得分:3)
您可以使用此功能,然后让所有拥有者继承自所有者。
然后,您可以使用所有者类私下包装 accessible_member 中使用的方法。
所有者现在可以访问 accessible_member 。朋友不是继承的,所以你可以提供(包装)必要的方法,这样所有继承所有者的类都可以使用 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上的最后一个示例。
答案 2 :(得分:1)
7.1.5.3 p2说:
[注意:这意味着,在一个 带有模板的类模板 type-parameter T,声明 朋友班T;是不正确的。]
因此,任何允许您使用它的任何解决方案都将符合非标准。
答案 3 :(得分:0)
如何简单地定义一个简单地从accessible_member继承的私有嵌套类型?像
这样的东西class Owner
{
template < typename T >
class accessible_member : public ::accessible_member< T > {};
};
当然,这仍然意味着任何人都可以使用原始的accessible_member
类型,因此可能没有太多用处。
答案 4 :(得分:0)
我能看到的唯一解决方法是相当难看并使用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>;
};
答案 5 :(得分:0)
就我所见,在C ++ 98下,这将有所改变。它使用g++-4.1 -Wall -Wextra -pedantic -ansi -std=c++98
只需更改
friend Owner;
到
struct Wrapper { typedef Owner type; };
friend class Wrapper :: type;
(我在Stackoverflow上得到了答案,这个问题出现了几次:Template parameter as a friend)