Tony The Lion
Tony The Lion

Reputation: 63310

Operator = is ambiguous (C++)

I have the following in a for loop and the compiler says 'operator = is ambiguous'. Not sure how to solve this issue, can anyone help?

rootelement = document->getDocumentElement();
    boost::interprocess::unique_ptr<DOMNodeIterator, release_deleter> itera (document->createNodeIterator(rootelement, DOMNodeFilter::SHOW_ALL, NULL, true));
    for(boost::interprocess::unique_ptr<DOMNode, release_deleter> current (itera->nextNode()); current != 0; current = boost::interprocess::unique_ptr<DOMNode, release_deleter> (itera->nextNode()))  // Last assignment on current is ambiguous

Full error:

*

\XMLDocument.cpp(193) : error C2593: 'operator =' is ambiguous
        c:\Program Files\boost\boost_1_44\boost\interprocess\smart_ptr\unique_ptr.hpp(249): could be 'boost::interprocess::unique_ptr<T,D> &boost::interprocess::unique_ptr<T,D>::operator =(int boost::interprocess::unique_ptr<T,D>::nat::* )'
        with
        [
            T=xercesc_3_1::DOMNode,
            D=release_deleter
        ]
        unique_ptr.hpp(211): or       'boost::interprocess::unique_ptr<T,D> &boost::interprocess::unique_ptr<T,D>::operator =(boost::interprocess::rv<boost::interprocess::unique_ptr<T,D>> &)'
        with
        [
            T=xercesc_3_1::DOMNode,
            D=release_deleter
        ]
        while trying to match the argument list '(boost::interprocess::unique_ptr<T,D>, boost::interprocess::unique_ptr<T,D>)'
        with
        [
            T=xercesc_3_1::DOMNode,
            D=release_deleter
        ]
        and
        [
            T=xercesc_3_1::DOMNode,
            D=release_deleter
        ]
  \XMLDocument.cpp(193) : see reference to class template instantiation 'boost::interprocess::detail::unique_ptr_error<T>' being compiled
        with
        [
            T=boost::interprocess::unique_ptr<xercesc_3_1::DOMNode,release_deleter>
        ]
    XMLDocument.cpp(193) : see reference to class template instantiation 'boost::interprocess::detail::unique_ptr_error<T>' being compiled
        with
        [
            T=xercesc_3_1::DOMNode *
        ]
       \XMLDocument.cpp(193) : see reference to class template instantiation 'boost::interprocess::detail::unique_ptr_error<T>' being compiled
        with
        [
            T=xercesc_3_1::DOMNode *
        ]
        XMLDocument.cpp(192) : see reference to class template instantiation 'boost::int
erprocess::detail::unique_ptr_error<T>' being compiled
        with
        [
            T=xercesc_3_1::DOMNodeIterator *
        ]

*

Upvotes: 1

Views: 1199

Answers (3)

Stephane Rolland
Stephane Rolland

Reputation: 39926

I think a std::unique_ptr can only be assigned with a call to std::move(). This is the way it explicitely loses the ownership of the underlying object.

std ::unique_ptr<T> upOldT = new T ;
std ::unique_ptr<T> pT = std ::move(upOldT) ;

As GMan has remarked, C++0x is not yet the current C++ standard, so it should be boost::interprocess::unique_ptr...

Upvotes: 1

GManNickG
GManNickG

Reputation: 504333

Like Stephane says, unique_ptr's maintain uniqueness unless you explicitly move them, or assign an rvalue to them. Normally, your code would be fine, but since you're faking rvalues, you'll need to move it explicitly.

I've never used boost::interprocess::unique_ptr, but it looks like you want this:

namespace bi = boost::interprocess; // do these please!
typedef bi::unique_ptr<DOMNode, release_deleter> node_ptr;
typedef bi::unique_ptr<DOMNodeIterator, release_deleter> iterator_ptr;

rootelement = document->getDocumentElement();
iterator_ptr itera(document->createNodeIterator(rootelement,
                                           DOMNodeFilter::SHOW_ALL, NULL, true));

for (node_ptr current(itera->nextNode()); current != 0;
         current = bi::move(node_ptr(itera->nextNode())))

Simpler might be:

for (node_ptr current(itera->nextNode()); current != 0;
         current.reset(itera->nextNode()))

Upvotes: 3

Jan
Jan

Reputation: 1847

I'm not sure, and haven't tried anything, but you can try:

current = itera->nextNode()

Then it will take only one of the ambiguities.

Upvotes: 0

Related Questions