代码之家  ›  专栏  ›  技术社区  ›  bua

模板问题('typename'不是模板函数参数)

  •  4
  • bua  · 技术社区  · 16 年前

    实际上,我在用英特尔编译器编译某些库时遇到了一个问题。

    问题是由模板引起的。 我想了解的是 **typename** as not模板函数参数和函数体内的变量声明

    例子:

    void func(typename sometype){..
    ...
    typename some_other_type;
    ..
    }
    

    ../../../libs/log/src/attribute_set.cpp(415): error: no operator "!=" matches these operands
                operand types are: boost::log_st::basic_attribute_set<wchar_t>::iter<'\000'> != boost::log_st::basic_attribute_set<wchar_t>::iter<'\000'>
          while (begin != end)
                       ^
              detected during instantiation of "void boost::log_st::basic_attribute_set<CharT>::erase(boost::log_st::basic_attribute_set<CharT>::iter<'\000'>, boost::log_st::basic_attribute_set<CharT>::iter<'\000'>) [with CharT=wchar_t]" at line 438
    
    ../../../boost/log/attributes/attribute_set.hpp(115): error: no operator "!=" matches these operands
                operand types are: boost::log_st::basic_attribute_set<wchar_t>::iter<'\000'> != boost::log_st::basic_attribute_set<wchar_t>::iter<'\000'>
                  if (it != m_pContainer->end())
    

    我想了解的是在函数体、参数声明中使用typename。

    前任。:

    template< typename CharT >
    struct basic_attribute_values_view< CharT >::implementation
    {
    
    public:
    ..
    ..
    void adopt_nodes( **typename attribu**te_set_type::const_iterator& it, **typename attribut**e_set_type::const_iterator end)
        {
            for (; it != end; ++it)
                push_back(it->first, it->second.get());
        }
    

    在不同的文件中,我:

    template< typename CharT >
    class basic_attribute_set
    {
        friend class basic_attribute_values_view< CharT >;
    
        //! Self type
        typedef basic_attribute_set< CharT > this_type;
    
    public:
        //! Character type
        typedef CharT char_type;
        //! String type
        typedef std::basic_string< char_type > string_type;
        //! Key type
        typedef basic_slim_string< char_type > key_type;
        //! Mapped attribute type
        typedef shared_ptr< attribute > mapped_type;
    
        //! Value type
        typedef std::pair< const key_type, mapped_type > value_type;
        //! Allocator type
        typedef std::allocator< value_type > allocator_type;
        //! Reference type
        **typedef typename allocator_type::reference reference;**
    
    3 回复  |  直到 16 年前
        1
  •  13
  •   sbi    11 年前

    typename 对于所谓的“依赖类型”。这些类型依赖于模板参数,在模板实例化之前是未知的。最好用一个例子来解释:

    struct some_foo {
      typedef int bar;
    };
    
    template< typename Foo >
    struct baz {
      typedef Foo::bar barbar; // wrong, shouldn't compile
    
      barbar f(); // would be fine if barbar were a type
    
      // more stuff...
    };
    

    那个 typedef 决定性的 barbar 类别名 为了让编译器能够检查模板是否存在明显的语法错误 它是用具体类型实例化的。原因是,当编译器第一次看到模板时(当它还没有用具体的模板参数实例化时),编译器不知道 Foo::bar 是一种类型。据它所知,我可能是有意的 baz 要用像这样的类型进行实例化

    struct some_other_foo {
      static int bar;
    };
    

    那么 Foo::bar 指的是 ,而不是类型,以及 baz::bar 这将是句法上的胡说八道。不知 Foo::bar 引用类型,编译器没有机会检查其中的任何内容 直接或间接地使用 芭芭拉 即使是最愚蠢的打字错误,直到 巴兹 是实例化的。使用适当的 , 看起来像这样:

    template< typename Foo >
    struct baz {
      typedef typename Foo::bar barbar;
    
      barbar f();
    
      // more stuff...
    };
    

    现在编译器至少知道了这一点 Foo::bar 应该是一个类型的名称,它使 芭芭拉 还有一个类型名。那么 f() 句法也可以。

    template< typename Foo >
    struct baz {
      Foo::bar<Foo> create_wrgl(); // wrong, shouldn't compile
    };
    

    当编译器“看到”时 Foo::bar bar<Foo 也可以是一个比较,让编译器对尾随的内容感到困惑 > Foo::bar

    template< typename Foo >
    struct baz {
      Foo::template bar<Foo> create_wrgl();
    };
    

    注意:特别是Visual C++仍然没有实现适当的两阶段查找(本质上:它实际上不检查模板,直到它们被实例化)。因此,它经常接受错误代码,而这些错误代码会丢失一个 或者 template .

        2
  •  6
  •   CAdaker    16 年前

    问题的关键 typename

    template<typename T>
    void f()
    {
        T::foo * x;
    }
    

    T::foo T::富 一个静态变量,我们在做乘法?

    因为编译器在读取模板时不知道T是什么,所以不知道这两种情况中哪一种是正确的。

    T::富 如果前面有 类别名 关键字,像这样:

    template<typename T>
    void f()
    {
        typename T::foo* x; //Definitely a pointer.
    }
    
        3
  •  0
  •   Test    16 年前

    根据您的代码:

    void func(typename sometype)
    {
        .....typename some_other_type;
        ..
    }
    

    如果上述代码不是模板的一部分,则不能使用g++编译,除非使用旧版本的g++。

    typename only can be used in template code
    

    而FC8或GNU C/++4.1x可能不会。

    请看

    http://code.google.com/p/effocore/source/browse/trunk/devel/effo/codebase/addons/inl/include/ringed_inl.h
    and 
    http://code.google.com/p/effocore/source/browse/trunk/devel/effo/codebase/addons/inl/include/cont_inl.h
    

    有关更多模板和typename示例。