模板的问题('typename的“不模板函数参数) [英] templates problem ('typename' as not template function parameter)

查看:153
本文介绍了模板的问题('typename的“不模板函数参数)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

其实我有一个问题,编译一些库,英特尔编译器。

这同样库已经使用g ++编译正确

问题是由模板引起的。
我想了解的是的声明
** **类型名称作为内部函数体不是模板函数的参数和变量声明

例如:

 无效FUNC(类型名sometype。这时候){..
...
TYPENAME some_other_type;
..
}

编纂这种code农产品下面的错误(英特尔),(海合会不索赔):
我有以下错误

  ../../../库/日志/ src目录/ attribute_set.cpp(415):错误:=没有运营商匹配这些操作数
            操作数类型是:提高:: log_st :: basic_attribute_set<&的wchar_t GT; :: ITER<'\\ 000'> !=提振:: log_st :: basic_attribute_set<&的wchar_t GT; :: ITER<'\\ 000'>
      同时(开始!=结束)
                   ^
          的虚化期间检测boost::log_st::basic_attribute_set<CharT>::erase(boost::log_st::basic_attribute_set<CharT>::iter<'\\000'>,提高:: log_st :: basic_attribute_set&LT;&图表GT; :: ITER&LT;'\\ 000'&GT;)[带有图表= wchar_t的]以线438../../../boost/log/attributes/attribute_set.hpp(115):错误:没有运营商!=这些操作数相匹配
            操作数类型是:提高:: log_st :: basic_attribute_set&LT;&的wchar_t GT; :: ITER&LT;'\\ 000'&GT; !=提振:: log_st :: basic_attribute_set&LT;&的wchar_t GT; :: ITER&LT;'\\ 000'&GT;
              如果(它= m_pContainer-&GT;!结束())

我想了解的是该类型名的职能机构,参数声明。

里面的用法

例如:

 模板&LT;类型名图&GT;
结构basic_attribute_values​​_view&LT;图&GT;执行::
{上市:
..
..
无效adopt_nodes(** typename的attribu ** te_set_type ::为const_iterator&功放;它,**类型名attribut ** e_set_type ::为const_iterator结束)
    {
        为(;!它到底= ++吧)
            的push_back(IT-&gt;首先,它 - &GT; second.get());
    }

在不同的文件中我有:

 模板&LT;类型名图&GT;
类basic_attribute_set
{
    友元类basic_attribute_values​​_view&LT;图取代;    //!自我型
    typedef的basic_attribute_set&LT;图&GT;这个类型;上市:
    //!字符类型
    的typedef图char_type;
    //!字符串类型
    的typedef的std :: basic_string的&LT; char_type&GT; STRING_TYPE;
    //!密钥类型
    typedef的basic_slim_string&LT; char_type&GT; key_type的;
    //!映射属性类型
    shared_ptr的typedef的LT&;属性&GT; mapped_type;    //!值类型
    的typedef的std ::对&LT;常量为key_type,mapped_type&GT; VALUE_TYPE;
    //!分配器类型
    的typedef的std ::分配器&LT; VALUE_TYPE&GT; allocator_type;
    //!引用类型
    **的typedef typename的allocator_type ::参考参考**


解决方案

您需要使用类型名称所谓依赖型。这些都是依赖于模板参数,不为人所知,直到模板实例类型。它使用一个例子可能是最好的解释:

 结构some_foo {
  的typedef INT吧;
};模板&LT; TYPENAME美孚&GT;
结构巴兹{
  typedef的富::酒吧BARBAR; //错了,不应该编译  BARBAR f()的;如果BARBAR是一个类型//将罚款  //更多的东西...
};

这是的typedef 定义 BARBAR 是一个需要类型名称为了使编译器能够前检查模板公然语法错误的 的被实例化一个具体类型。其原因是,当编译器看到的第一次模板(当它不是用混凝土模板参数尚未实例化),编译器不知道是否富::酒吧是一个类型。对于所有它知道,我可能意图巴兹同类型的像这样的实例化

 结构some_other_foo {
  静态INT吧;
};

在这种情况下,富::酒吧将涉及到的对象的,不是一个类型,而的定义巴兹::酒吧将语法无稽之谈。不知道富::酒吧是否是指一类,编译器没有机会在巴兹检查什么,是直接或间接使用 BARBAR ,即使是最愚蠢的错别字,直到巴兹被实例化。使用合适的类型名称巴兹是这样的:

 模板&LT; TYPENAME美孚&GT;
结构巴兹{
  的typedef typename的富::酒吧BARBAR;  BARBAR f()的;  //更多的东西...
};

现在的编译器至少知道富::酒吧应该是一个类型,这使得名称 BARBAR 类型名称了。因此,的F()是语法行,得声明。

顺便说一下,有类似的问题与模板代替类型:

 模板&LT; TYPENAME美孚&GT;
结构巴兹{
  富::酒吧和LT;富&GT; create_wrgl(); //错了,不应该编译
};

在编译器看到富::酒吧它不知道它是什么,所以巴≤;美孚你同样可以做个比较,让编译器困惑的结尾&GT; 。在这里,你需要给编译器一个暗示,富::酒吧应该是一个模板的名称:

 模板&LT; TYPENAME美孚&GT;
结构巴兹{
  富::模板巴≤;美孚&GT; create_wrgl();
};

请注意:值得注意的是VISUAL C ++仍然没有实施适当的两阶段查找(本质:它并没有真正检查模板,直到它们被实例化)。为此经常接受错误的code,它错过了类型名称模板

Actually I've a problem with compiling some library with intel compiler.

This same library has been compiled properly with g++.

Problem is caused by templates. What I'd like to understand is the declaration of **typename** as not template function parameter and variable declaration inside function body

example:

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

Compilation this kind of code produce following errors (intel),(gcc doesn't claim): I've got following errors

../../../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())

What I'd like to understand is the usage of the typename inside the body of functions, parameter declarations.

ex.:

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

in different file I've:

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

解决方案

You need to use typename for so-called "dependent types". Those are types that depend on a template argument and are not known until the template is instantiated. It's probably best explained using an example:

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

That typedef defining barbar is one that requires a typename in order for the compiler to be able to check the template for blatant syntactic errors before it is instantiated with a concrete type. The reason is that, when the compiler sees the template for the first time (when it's not instantiated with concrete template parameters yet), the compiler doesn't know whether Foo::bar is a type. For all it know, I might intent baz to be instantiated with types like this one

struct some_other_foo {
  static int bar;
};

in which case Foo::bar would refer to an object, not a type, and the definition of baz::bar would be syntactic nonsense. Without knowing whether Foo::bar refers to a type, the compiler has no chance to check anything within baz that's directly or indirectly using barbar for even the most stupid typos until baz is instantiated. Using the proper typename, baz looks like this:

template< typename Foo >
struct baz {
  typedef typename Foo::bar barbar;

  barbar f();

  // more stuff...
};

Now the compiler at least knows that Foo::bar is supposed to be the name of a type, which makes barbar a type name, too. So the declaration of f() is syntactical OK, too.

By the way, there's a similar problem with templates instead of types:

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

When the compiler "sees" Foo::bar it doesn't know what it is, so bar<Foo could just as well be a comparison, leaving the compiler confused about the trailing >. Here, too, you need to give the compiler a hint that Foo::bar is supposed to be the name of a template:

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

Beware: Notably Visual C++ still doesn't implement proper two-phase lookup (in essence: it doesn't really check templates until they are instantiated). Therefor it often accepts erroneous code that misses a typename or a template.

这篇关于模板的问题('typename的“不模板函数参数)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆