Michael Fawcett writes:
Can someone confirm if the attached code doesn't compile intentionally
or if this is a bug? I'm sorry for not posting a minimal example but
I couldn't figure out how to reduce the problem.
Ping with complete code this time. Hopefully that will help with a response. I
also added my work-around to the code.
#include
#include
#include
#include
#include
#include
#include
#include <cassert>
#include <vector>
//#define POSSIBLE_FIX
#ifdef POSSIBLE_FIX
// Not sure if this is a bug in Boost (doubt it) or just necessary
// since CComBSTR overloads the address-of operator to return a
// type (BSTR) that is not implicitly convertible to CComBSTR *.
namespace boost {
namespace detail {
template
struct operator_arrow_result
{
typedef typename mpl::if_<
is_reference<Reference>
, Pointer
, operator_arrow_proxyATL::CComBSTR
>::type type;
static type make(Reference x)
{
return implicit_cast<type>(boost::addressof(x));
}
};
}
}
#endif
namespace detail {
template <typename T>
struct CAdapt_pointee { };
template <typename T>
struct CAdapt_pointee {
typedef T type;
};
template
struct m_T_type_add_const_conditionally {
typedef typename CAdapt_pointee::type type;
};
template
struct m_T_type_add_const_conditionally {
typedef typename boost::add_const::type>::type type;
};
template <typename T>
struct m_T_type {
typedef typename m_T_type_add_const_conditionally::type type;
};
}
template <class Iterator>
class CAdapt_iterator : public
boost::iterator_adaptor
<
CAdapt_iterator<Iterator>,
Iterator,
typename detail::m_T_type<Iterator>::type,
typename boost::iterator_category<Iterator>::type,
typename detail::m_T_type<Iterator>::type &
> {
private:
struct enabler { };
typedef typename detail::m_T_type<Iterator>::type &reference_type;
public:
CAdapt_iterator() { }
CAdapt_iterator(Iterator p) : CAdapt_iterator::iterator_adaptor_(p) { }
template <class OtherValue>
CAdapt_iterator(const CAdapt_iterator<OtherValue> &other,
typename boost::enable_if,
enabler>::type = enabler())
: CAdapt_iterator::iterator_adaptor_(other.base()) { }
private:
friend class boost::iterator_core_access;
reference_type dereference() const { return this->base()->m_T; }
};
template <typename Iterator>
CAdapt_iterator<Iterator> make_CAdapt_iterator(Iterator i) {
return CAdapt_iterator<Iterator>(i);
}
int main() {
std::vector buffer(1, CComBSTR(L"Hello, World!"));
assert(*make_CAdapt_iterator(buffer.begin()) == L"Hello, World!");
// This line causes the compile-error if POSSIBLE_FIX is not defined
make_CAdapt_iterator(buffer.begin())->Empty();
assert(buffer[0].m_T.Length() == 0);
}
--Michael Fawcett