模板编程 - 常见错误

时间:2010-09-22 03:39:54

标签: c++ templates wiki

  

可能重复:
  C++ template gotchas

您好,

我刚刚进入SO的第二个月,我已经看到足够数量的帖子与模板的几个常见问题有关。在这个上制作一个小维基是一个好主意(遗憾的是我不知道如何制作一个)?

这个想法是提供一个明确的参考this(GMan的最爱)

这是我的第一个

http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12

如果已存在或如果这个想法没有吸引力,请随时投票支持关闭。我也会投票赞成:)

3 个答案:

答案 0 :(得分:1)

typename

的快速摘要

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)

unqualified name lookup

期间永远不会搜索依赖的碱基
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>
}