title: Compilation error on ambiguous type in code using boost::spirit
body: <p>If I write this code it still compiles:</p>
  
  <pre><code>namespace MyNamespace
  {
  
  struct STreeConstructionRuleQuery : std::string {};
  struct STreeConstructionRuleOperation : std::string {};
  struct STreeConstructionRuleOperand : std::string {};
  struct STreeConstructionRuleCondition : std::string {};
  
  struct STreeConstructionRuleOperationWithOperands : boost::tuple&lt;STreeConstructionRuleOperation, std::vector&lt;STreeConstructionRuleOperand&gt; &gt; {};
  
  struct STreeConstructionRule
  {
      boost::optional&lt;std::vector&lt;std::vector&lt;STreeConstructionRuleOperationWithOperands&gt; &gt; &gt; m_sAssertion;
      STreeConstructionRuleQuery m_sQuery;
      STreeConstructionRuleOperationWithOperands m_sAction;
      boost::optional&lt;STreeConstructionRuleCondition&gt; m_sCondition;
  };
  
  }
  
  
  BOOST_FUSION_ADAPT_STRUCT(
      MyNamespace::STreeConstructionRule,
      (boost::optional&lt;std::vector&lt;std::vector&lt;MyNamespace::STreeConstructionRuleOperationWithOperands&gt; &gt; &gt;, m_sAssertion)
      (MyNamespace::STreeConstructionRuleQuery, m_sQuery)
      (MyNamespace::STreeConstructionRuleOperationWithOperands, m_sAction)
      (boost::optional&lt;MyNamespace::STreeConstructionRuleCondition&gt;, m_sCondition)
  )
  
  
  namespace MyNamespace
  {
  
  namespace qi = boost::spirit::qi;
  namespace ascii = boost::spirit::ascii;
  namespace phoenix = boost::phoenix;
  
  template &lt;typename Iterator&gt;
  struct STreeContructionRulesGrammar : qi::grammar&lt;Iterator, std::vector&lt;STreeConstructionRule&gt;(), ascii::space_type&gt;
  {
      qi::rule&lt;Iterator, std::vector&lt;STreeConstructionRule&gt;(), ascii::space_type&gt; m_oStart;
      qi::rule&lt;Iterator, qi::unused_type(), ascii::space_type&gt; m_oComment;
      qi::rule&lt;Iterator, STreeConstructionRule(), ascii::space_type&gt; m_oRule;
  
      STreeContructionRulesGrammar() : STreeContructionRulesGrammar::base_type(m_oStart)
      {
          m_oStart = *(m_oComment | m_oRule [phoenix::push_back(qi::_val, qi::_1)]);
          m_oComment = (("--&gt;" &gt;&gt; *(qi::char_) &gt;&gt; "&lt;--") | ('#' &gt;&gt; *(qi::char_ - qi::char_("\n\r")))); 
      }
  
  };
  }
  </code></pre>
  
  <p>But when I change the definition of <code>STreeConstructionRuleOperand</code> to</p>
  
  <pre><code>struct STreeConstructionRuleOperand : boost::variant&lt;int&gt; {};
  </code></pre>
  
  <p>I get the following compilation error (STLPort is used instead of STL):</p>
  
  <pre><code>1&gt;d:\commonlib\include\boost\variant\variant.hpp(1373) : error C2666: 'boost::variant&lt;T0_&gt;::convert_construct' : 2 overloads have similar conversions
  1&gt;        with
  1&gt;        [
  1&gt;            T0_=int
  1&gt;        ]
  1&gt;        d:\commonlib\include\boost\variant\variant.hpp(1358): could be 'void boost::variant&lt;T0_&gt;::convert_construct&lt;int,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_&gt;(const boost::variant&lt;T0_&gt; &amp;,long)'
  1&gt;        with
  1&gt;        [
  1&gt;            T0_=int
  1&gt;        ]
  1&gt;        d:\commonlib\include\boost\variant\variant.hpp(1289): or       'void boost::variant&lt;T0_&gt;::convert_construct&lt;const T&gt;(T &amp;,int,boost::mpl::false_)'
  1&gt;        with
  1&gt;        [
  1&gt;            T0_=int,
  1&gt;            T=MyNamespace::STreeConstructionRuleOperand
  1&gt;        ]
  1&gt;        while trying to match the argument list '(const MyNamespace::STreeConstructionRuleOperand, long)'
  1&gt;        d:\commonlib\include\boost\fusion\container\vector\detail\vector_n.hpp(45) : see reference to function template instantiation 'boost::variant&lt;T0_&gt;::variant&lt;MyNamespace::STreeConstructionRuleOperand&gt;(const T &amp;)' being compiled
  1&gt;        with
  1&gt;        [
  1&gt;            T0_=int,
  1&gt;            T=MyNamespace::STreeConstructionRuleOperand
  1&gt;        ]
  1&gt;        d:\commonlib\include\stlport\stl\_uninitialized.h(93) : see reference to function template instantiation 'void stlpd_std::_Destroy_Range&lt;_OutputIter&gt;(_ForwardIterator,_ForwardIterator)' being compiled
  1&gt;        with
  1&gt;        [
  1&gt;            _OutputIter=stlpd_std::vector&lt;MyNamespace::STreeConstructionRuleOperationWithOperands&gt; *,
  1&gt;            _ForwardIterator=stlpd_std::vector&lt;MyNamespace::STreeConstructionRuleOperationWithOperands&gt; *
  1&gt;        ]
  1&gt;        d:\commonlib\include\stlport\stl\_uninitialized.h(113) : see reference to function template instantiation '_OutputIter stlpd_std::priv::__ucopy&lt;_InputIter,_OutputIter,ptrdiff_t&gt;(_RandomAccessIter,_RandomAccessIter,_OutputIter,const stlpd_std::random_access_iterator_tag &amp;,_Distance *)' being compiled
  1&gt;        with
  1&gt;        [
  1&gt;            _OutputIter=stlpd_std::vector&lt;MyNamespace::STreeConstructionRuleOperationWithOperands&gt; *,
  1&gt;            _InputIter=const stlpd_std::vector&lt;MyNamespace::STreeConstructionRuleOperationWithOperands&gt; *,
  1&gt;            _RandomAccessIter=const stlpd_std::vector&lt;MyNamespace::STreeConstructionRuleOperationWithOperands&gt; *,
  1&gt;            _Distance=ptrdiff_t
  1&gt;        ]
  1&gt;        d:\commonlib\include\stlport\stl\_vector.h(249) : see reference to function template instantiation '_OutputIter stlpd_std::priv::__ucopy_ptrs&lt;const stlpd_std::vector&lt;_Tp&gt;*,stlpd_std::vector&lt;_Tp&gt;*&gt;(_InputIter,_InputIter,_OutputIter,const stlpd_std::__false_type &amp;)' being compiled
  1&gt;        with
  1&gt;        [
  1&gt;            _OutputIter=stlpd_std::vector&lt;MyNamespace::STreeConstructionRuleOperationWithOperands&gt; *,
  1&gt;            _Tp=MyNamespace::STreeConstructionRuleOperationWithOperands,
  1&gt;            _InputIter=const stlpd_std::vector&lt;MyNamespace::STreeConstructionRuleOperationWithOperands&gt; *
  1&gt;        ]
  1&gt;        d:\commonlib\include\stlport\stl\_vector.h(246) : while compiling class template member function 'stlpd_std::priv::_NonDbg_vector&lt;_Tp,_Alloc&gt;::_NonDbg_vector(const stlpd_std::priv::_NonDbg_vector&lt;_Tp,_Alloc&gt; &amp;)'
  1&gt;        with
  1&gt;        [
  1&gt;            _Tp=stlpd_std::vector&lt;MyNamespace::STreeConstructionRuleOperationWithOperands&gt;,
  1&gt;            _Alloc=stlpd_std::allocator&lt;stlpd_std::vector&lt;MyNamespace::STreeConstructionRuleOperationWithOperands&gt;&gt;
  1&gt;        ]
  1&gt;        d:\commonlib\include\stlport\stl\debug\_iterator.h(378) : see reference to class template instantiation 'stlpd_std::priv::_NonDbg_vector&lt;_Tp,_Alloc&gt;' being compiled
  1&gt;        with
  1&gt;        [
  1&gt;            _Tp=stlpd_std::vector&lt;MyNamespace::STreeConstructionRuleOperationWithOperands&gt;,
  1&gt;            _Alloc=stlpd_std::allocator&lt;stlpd_std::vector&lt;MyNamespace::STreeConstructionRuleOperationWithOperands&gt;&gt;
  1&gt;        ]
  1&gt;        d:\commonlib\include\stlport\stl\debug\_vector.h(106) : see reference to class template instantiation 'stlpd_std::priv::__construct_checker&lt;_Container&gt;' being compiled
  1&gt;        with
  1&gt;        [
  1&gt;            _Container=stlpd_std::priv::_NonDbg_vector&lt;stlpd_std::vector&lt;MyNamespace::STreeConstructionRuleOperationWithOperands&gt;,stlpd_std::allocator&lt;stlpd_std::vector&lt;MyNamespace::STreeConstructionRuleOperationWithOperands&gt;&gt;&gt;
  1&gt;        ]
  1&gt;        d:\commonlib\include\boost\optional\optional.hpp(110) : see reference to class template instantiation 'stlpd_std::vector&lt;_Tp&gt;' being compiled
  1&gt;        with
  1&gt;        [
  1&gt;            _Tp=stlpd_std::vector&lt;MyNamespace::STreeConstructionRuleOperationWithOperands&gt;
  1&gt;        ]
  1&gt;        d:\commonlib\include\boost\optional\optional.hpp(113) : see reference to class template instantiation 'boost::optional_detail::aligned_storage&lt;T&gt;::dummy_u' being compiled
  1&gt;        with
  1&gt;        [
  1&gt;            T=stlpd_std::vector&lt;stlpd_std::vector&lt;MyNamespace::STreeConstructionRuleOperationWithOperands&gt;&gt;
  1&gt;        ]
  1&gt;        d:\commonlib\include\boost\optional\optional.hpp(450) : see reference to class template instantiation 'boost::optional_detail::aligned_storage&lt;T&gt;' being compiled
  1&gt;        with
  1&gt;        [
  1&gt;            T=stlpd_std::vector&lt;stlpd_std::vector&lt;MyNamespace::STreeConstructionRuleOperationWithOperands&gt;&gt;
  1&gt;        ]
  1&gt;        d:\commonlib\include\boost\optional\optional.hpp(457) : see reference to class template instantiation 'boost::optional_detail::optional_base&lt;T&gt;' being compiled
  1&gt;        with
  1&gt;        [
  1&gt;            T=stlpd_std::vector&lt;stlpd_std::vector&lt;MyNamespace::STreeConstructionRuleOperationWithOperands&gt;&gt;
  1&gt;        ]
  1&gt;        d:\preformator\sources\prefcore\preftreeconstructor.cpp(52) : see reference to class template instantiation 'boost::optional&lt;T&gt;' being compiled
  1&gt;        with
  1&gt;        [
  1&gt;            T=stlpd_std::vector&lt;stlpd_std::vector&lt;MyNamespace::STreeConstructionRuleOperationWithOperands&gt;&gt;
  1&gt;        ]
  </code></pre>
  
  <p>This is the only error the compiler reports. I don't see any ambiguity but the compiler does. What is the reason for this error and how it should be fixed?</p>