可能重复:
C++ template gotchas
您好,
我刚刚进入SO的第二个月,我已经看到足够数量的帖子与模板的几个常见问题有关。在这个上制作一个小维基是一个好主意(遗憾的是我不知道如何制作一个)?
这个想法是提供一个明确的参考this(GMan的最爱)
这是我的第一个
http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12
如果已存在或如果这个想法没有吸引力,请随时投票支持关闭。我也会投票赞成:)
答案 0 :(得分:1)
typename
关键字在C ++中有两个含义。 typename
可用作模板参数列表中class
的替代。
// These two lines mean exactly the same thing.
template<typename A> class Foo {};
template<class A> class Foo {};
另一个原因更复杂。 typename
告诉编译器,从属名称实际上是一种类型。
考虑:
template<typename T>
struct Bar
{
typedef T MyType; // Okay.
typedef T::Type OtherType; // Wrong.
};
这是错误的,因为编译器认为T::Type
实际上不是类型,因此typedef
失败。 T
可能将Type
定义为不是类型的东西(如静态成员),因此编译器必须默认将T::Type
视为非类型,因为它不知道{ {1}}直到它被实例化。在这种情况下,T
是标准名称依赖名称的标准。请注意T::Type
是一个非依赖名称,因为编译器知道T
实际上是一个类型(它是模板类型参数之一),所以这不是需要T
。
在这种情况下,您必须提示编译器:
typename
不幸的是,由于编译器错误,编译器可能会编译没有template<typename T>
struct Bar
{
typedef T MyType; // Okay.
typedef typename T::Type OtherType; // Okay.
};
的代码段而不会出错,即使它不合法!
答案 1 :(得分:1)
使用推导出的模板类型的一些有趣的东西。
编译器以不同方式处理以下情况。
struct F {
typedef int value_type;
};
struct B : F {
B::value_type value; // some compilers, edg
typename B::value_type value; // other compilers, gcc
BOOST_DEDUCED_TYPENAME B::value_type value; // Boost!!!
};
为了让这个疯狂,nvcc cuda编译器实际上是两个编译器,edg和gcc,汇总成一个处理相同文件的编译器。但是,typename扣除对于它们都是不同的,因此它使得BOOST_DEDUCED_TYPENAME不合适。 : - (
答案 2 :(得分:0)
struct base{
virtual void f(){}
};
template<class T> struct anotherbase{
virtual void f(){}
};
template<class T> struct derived : base, anotherbase<T>{
void g(){f();}
};
int main(){
derived<int> d;
d.g(); // not ambiguous. should call base::f
// unqualified name 'f' is not looked up
// anotherbase<int>
}