2010-01-29 6 views
1

j'ai un problème étrange avec des modèles et des espaces de noms ...problème espace de noms modèle étrange

je le code suivant qui compile bien ..

using namespace boost::multi_index; 

template < typename OT, typename KT, KT (OT::* KM)() const, typename KC, typename CMP > 
class OrderBook 
{ 
public: 
    OrderBook() {} 
    ~OrderBook() {} 

    typedef multi_index_container< 
     OT, 
     indexed_by< 
      ordered_unique< 
       const_mem_fun< OT, KT, KM >, 
       KC 
      >, 
      ordered_unique< 
       identity<OT>, 
       CMP 
      > 
     > 
    > Container; 

    typedef typename Container::template nth_index<0>::type index_0; 
    typedef typename Container::template nth_index<1>::type index_1; 

    typedef typename index_0::const_iterator const_iterator_0; 
    typedef typename index_1::const_iterator const_iterator_1; 

    const_iterator_0 begin0() const { return _container.get<0>().begin(); } 
    const_iterator_0 end0() const { return _container.get<0>().end(); } 


public: 
    Container _container; 
}; 

Toutefois, en raison d'une collision d'espace de noms lorsque insérer ce code dans un autre projet que je dois avoir ... (Remarquez comment j'ai dû enlever l'aide de namespace boost::multi_index et spécifier manuellement si nécessaire

template < typename OT, typename KT, KT (OT::* KM)() const, typename KC, typename CMP > 
class OrderBook 
{ 
public: 
    OrderBook() {} 
    ~OrderBook() {} 

    typedef boost::multi_index::multi_index_container< 
     OT, 
     boost::multi_index::indexed_by< 
      boost::multi_index::ordered_unique< 
       boost::multi_index::const_mem_fun< OT, KT, KM >, 
       KC 
      >, 
      boost::multi_index::ordered_unique< 
       boost::multi_index::identity<OT>, 
       CMP 
      > 
     > 
    > Container; 

    typedef typename Container::template nth_index<0>::type index_0; 
    typedef typename Container::template nth_index<1>::type index_1; 

    typedef typename index_0::const_iterator const_iterator_0; 
    typedef typename index_1::const_iterator const_iterator_1; 

    const_iterator_0 begin0() const { return _container.get<0>().begin(); } 
    const_iterator_0 end0() const { return _container.get<0>().end(); } 


public: 
    Container _container; 
}; 

ce qui me donne t Il suit l'erreur de g ++.

In member function 'typename boost::multi_index::multi_index_container<OT, boost::multi_index::indexed_by<boost::multi_index::ordered_unique<boost::multi_index::const_mem_fun<OT, KT, KM>, KC, mpl_::na>, boost::multi_index::ordered_unique<boost::multi_index::identity<Value>, CMP, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<_CharT> >::nth_index<0>::type::const_iterator OrderBook<OT, KT, KM, KC, CMP>::begin0() const': 

error: expected primary-expression before ')' token 


In member function 'typename boost::multi_index::multi_index_container<OT, boost::multi_index::indexed_by<boost::multi_index::ordered_unique<boost::multi_index::const_mem_fun<OT, KT, KM>, KC, mpl_::na>, boost::multi_index::ordered_unique<boost::multi_index::identity<Value>, CMP, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<_CharT> >::nth_index<0>::type::const_iterator OrderBook<OT, KT, KM, KC, CMP>::end0() const': 

error: expected primary-expression before ')' token 

Désolé pour les longs messages d'erreur, je ne considère les nettoyer, mais je pensais que je ferais mieux de les laisser intactes au cas où j'enlevé quelque chose de crucial.

J'ai essayé ...

typedef typename Container::template boost::multi_index::nth_index<0>::type index_0; 
typedef typename Container::template boost::multi_index::nth_index<1>::type index_1; 

et il vient de faire g ++ même garance :(

Toutes les idées?

+0

Quelle version de g ++ utilisez-vous? Exemple parfaitement compilable avec VC++ 2005 BTW. –

+0

VC8 est assez laxiste en ce qui concerne les noms dépendants, vous n'avez pas toujours à préfixer avec 'typename' et' template' où la norme vous obligerait à le faire. –

+0

C'est un gcc raisonnablement ancien 4.1.2. – ScaryAardvark

Répondre

6

Prefix get<0>() avec template:

const_iterator_0 begin0() const { return _container.template get<0>().begin(); } 
const_iterator_0 end0 () const { return _container.template get<0>().end(); } 

similaires à typename pour les types dépendants, modèles dépendants doivent être préfixé par template:

struct X { 
    template<class T> void f(); 
}; 

template<class T> 
void test() { 
    T::f<int>(); // ill-formed 
    T::template f<int>(); // ok 
} 

// ... 
test<X>(); 

Et pour les curieux, c'est §14.2/4:

Lorsque le nom d'une spécialisation de modèle de membre apparaît après. ou -> dans un postfix-expression, ou après imbriqué-name-spécificateur dans un -id qualifié, et le postfix-expression ou id qualifié dépend explicitement sur un modèle paramètres (14.6.2), le nom du modèle de membre doit être précédé du préfixe par le modèle de mot clé. Sinon, le nom est supposé nommer un non-modèle .

+0

Merci. Ça a arrangé ça ... Puis-je vous demander comment vous l'avez trouvé ou quelle référence vous avez utilisé? À moins de coller le mot «gabarit» partout, j'aurais _NEVER_ découvert cela .... – ScaryAardvark

+0

ScaryAardvark, je laisse gcc me pointer vers la ligne où le problème était et j'ai remarqué que vous vous référez à une fonction de membre de modèle de '_container' et que' _container' était un type d'argument de modèle. Les modèles dépendants doivent être préfixés par 'template', similaire à' typename' pour les types dépendants. –

+0

Correction, je veux dire que '_container' est un type dépendant de l'argument template - si c'est le bon terme. –

0

Peut-être que je devine que certaines de ces fonctions ne sont pas dans la boost::multi_index espace de noms: indexed_b, ordered_unique, const_mem_fun ou identity

+0

Non, ils sont tous dans l'espace de noms boost :: multi_index .. J'avais besoin de les spécifier exactement parce que j'avais un doublon avec "identity". – ScaryAardvark