问题描述
其实我有一个问题,编译一些库,英特尔编译器。
这同样库已经使用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的“不模板函数参数)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!