私はブールへのキャストをオーバーロードする私自身のptrで侵入型ptrをラップしようとしていました。さらに、私のptrでは、いくつかのboost侵入型ptrmethodsへのアクセスを制限したいと思います。最初は私のptrのプライベートメンバーとしてブースト介入ptrを使用し、boolイディオムを使用しました。それはうまくいき、boolイディオムを使用しました。 私自身の特別な理由から、新しいptrが侵入型のptrを増強する必要があったので、私は私的継承を使用しましたが、それはうまくいきませんでした。何らかの理由でgccが私のptrを、侵入型のptrとして処理しようとし、公開されているboolイディオムを使用することを拒否します。GCCは私的継承を親に変換します
#include <boost/intrusive_ptr.hpp>
#include <stdio.h>
class Object
{
public:
Object() : _refCount(0) {}
void addRef() { _refCount++; }
unsigned int releaseRef() { return --_refCount; }
private:
unsigned int _refCount;
};
inline void intrusive_ptr_release(Object* p)
{
if (p->releaseRef() == 0)
{
delete p;
}
}
inline void intrusive_ptr_add_ref(Object* p)
{
p->addRef();
}
// Option A: using private member
template<class ObjectT>
class PtrA
{
public:
explicit PtrA(ObjectT* obj) : _obj(obj) {}
PtrA() {}
ObjectT* operator->() { return _obj.operator->(); }
const ObjectT* operator->() const { return _obj.operator->(); }
ObjectT* get() { return _obj.get(); }
const ObjectT* get() const { return _obj.get(); }
typedef const ObjectT* (PtrA::*unspecified_bool_type)() const;
operator unspecified_bool_type() const
{
if (_obj != NULL)
{
printf("ptr is not null\n");
}
return _obj.get() == 0 ? 0: (unspecified_bool_type)&PtrA::get;
}
private:
boost::intrusive_ptr<ObjectT> _obj;
};
// Option B: using private inheritance
template<class ObjectT>
class PtrB : private boost::intrusive_ptr<ObjectT>
{
public:
explicit PtrB(ObjectT* obj) : boost::intrusive_ptr<ObjectT>(obj) {}
PtrB() {}
using boost::intrusive_ptr<ObjectT>::operator->;
using boost::intrusive_ptr<ObjectT>::get;
typedef const ObjectT* (PtrB::*unspecified_bool_type)() const;
operator unspecified_bool_type() const
{
const ObjectT* p = boost::intrusive_ptr<ObjectT>::get();
if (p != NULL)
{
printf("ptr is not null\n");
}
return p == 0 ? 0 : (unspecified_bool_type)&PtrB::get;
}
};
int main()
{
// this verison compiles
// PtrA<Object> obj(new Object());
PtrB<Object> obj(new Object());
if (obj == NULL)
{
printf("object is null\n");
}
if (!obj)
{
printf("object is null\n");
}
return 0;
}
コンパイル・エラーでこのコードの結果にPtrBを使用する:ここで はそれを示すサンプルコードです
g++ -std=c++11 ./test.cpp
...
./test.cpp: In function 'int main()':
./test.cpp:88:16: error: 'boost::intrusive_ptr<Object>' is an inaccessible base of 'PtrB<Object>'
if (obj == NULL)
^
In file included from /usr/include/boost/smart_ptr/intrusive_ptr.hpp:167:0,
from /usr/include/boost/intrusive_ptr.hpp:16,
from ./test.cpp:1:
/usr/include/boost/smart_ptr/detail/operator_bool.hpp:60:10: error: 'bool boost::intrusive_ptr<T>::operator!() const [with T = Object]' is inaccessible
bool operator!() const BOOST_NOEXCEPT
^
./test.cpp:92:10: error: within this context
if (!obj)
^
./test.cpp:92:10: error: 'boost::intrusive_ptr<Object>' is not an accessible base of 'PtrB<Object>'
ブースト侵入PTRが個人的に継承されている場合は、GCCは、それを使用するために何をしようとしません代わりに公共のブールのイディオムですか? は、私は、GCC 4.8.5
@WhiZTiM私はOPの例を修正しました。あなたはコメント行の変更が必要です。 – Barry
@Barry、Ohhh ...盲目的に...はい、..再現されました。あなたの答えはそれを説明します。 :-) – WhiZTiM