【问题标题】:strange template namespace problem奇怪的模板命名空间问题
【发布时间】:2010-01-29 14:28:49
【问题描述】:

我遇到了一个关于模板和命名空间的奇怪问题...

我有以下编译好的代码..

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;
};

但是,由于在我将此代码插入另一个项目时发生命名空间冲突,我必须...(注意我必须删除 using namespace boost::multi_index 并在需要的地方手动指定它

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;
};

这给了我来自 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

抱歉,错误消息太长了,我确实考虑过清理它们,但我想我最好保持它们完好无损,以防我删除了一些重要的东西。

我试过了……

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;

这让 g++ 更加疯狂:(

有什么想法吗?

【问题讨论】:

  • 您使用的是哪个版本的 g++?使用 VC++2005 BTW 完美编译的示例。
  • VC8 在依赖名称方面相当宽松,您不必总是在标准要求的地方加上 typenametemplate 前缀。
  • 这是一个相当老的 gcc 4.1.2。

标签: c++ templates namespaces


【解决方案1】:

前缀get&lt;0&gt;()template

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

依赖类型类似于typename,依赖模板必须以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>();

对于好奇的人,那就是 §14.2/4

当成员模板的名称 专业化出现在 之后。或-> 在后缀表达式中或之后 嵌套名称说明符 合格的 id 和 后缀表达式或限定 ID 显式地依赖于 模板参数(14.6.2), 成员模板名称必须加前缀 通过关键字模板。否则 假定名称为 a 非模板。

【讨论】:

  • 谢谢。那解决了它..我能问一下你是如何发现这个的或者你使用了什么参考。除非在任何地方都贴上“模板”这个词,否则我永远不会发现这个......
  • ScaryAardvark,我让 gcc 指向问题所在的实际行,并注意到您引用了 _container 的模板成员函数,并且 _container 是模板参数类型。依赖模板必须以template 为前缀,类似于依赖类型的typename
  • 更正,我的意思是 _container 实际上是一个模板参数依赖类型 - 如果这是正确的术语。
【解决方案2】:

也许我可以猜到其中一些函数不在boost::multi_index 命名空间中:indexed_bordered_uniqueconst_mem_funidentity

【讨论】:

  • 不,它们都在 boost::multi_index 命名空间中。我需要准确地指定它们,因为我有一个带有“身份”的重复项。
猜你喜欢
  • 1970-01-01
  • 2011-05-26
  • 2020-01-14
  • 2017-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-12
  • 2012-08-26
相关资源
最近更新 更多