Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++模板:如果我们在模板类中放置错误的东西会发生什么_C++_Templates - Fatal编程技术网

C++模板:如果我们在模板类中放置错误的东西会发生什么

C++模板:如果我们在模板类中放置错误的东西会发生什么,c++,templates,C++,Templates,C++模板允许我们使用模板参数在对象中放置任何内容。但是,如果我们的模板参数使用属于某些类型的函数/变量,我们如何检查 template<typename BarType>rguments class Foo { public: Foo() { bar = new BarType() } private: BarType * bar; } Foo<Bar> … BarType可以是从Bar超类派生的任何东西 如果我们在Foo类中调用一些

C++模板允许我们使用模板参数在对象中放置任何内容。但是,如果我们的模板参数使用属于某些类型的函数/变量,我们如何检查

template<typename BarType>rguments

class Foo {

public:

     Foo() { bar = new BarType() }

private:

     BarType * bar;

}

Foo<Bar> …
BarType可以是从Bar超类派生的任何东西


如果我们在Foo类中调用一些只属于Bar的函数,会发生什么?如果我们通过非BarType,会发生什么?我们还需要检查吗?

如果模板化的代码引用了在您尝试实例化模板时实际参数未提供的成员,则会出现编译时错误。所以别担心,你不会打破任何东西


将模板视为一种代码生成机制。有时,生成的代码是否真正有意义,只能在您实际尝试时才能确定。

无论您在tempalte参数列表中给出什么,都是一个简单的占位符。编译器将根据用于实例化模板类的对象类型,使用适当的类型重新编译。如果对象不能满足函数中的操作,则会出现编译时错误。使用“T”作为占位符也是一种很好的做法。

给定下面的类模板TempFoo,您可以看到它在其构造函数中调用模板化T类型的示例函数。前两种类型有效,因为它们都定义了示例;第三个没有

template<typename T>
class TempFoo
{
    void TempFoo() {
        T obj;
        obj.example();
    }
};

class First {
    void example() {}
};

class Second {
    void example() {}
};

class Third {
};

int main()
{
     TempFoo<First> f; // works
     TempFoo<Second> s; // works
     TempFoo<Third> t; // doesn't

}

确保模板参数派生自基类的简单方法:

template<typename BarType>
class Foo 
{
    // ...
    ~Foo() { Bar* p = (BarType*)0; }
};

编译器将对赋值进行类型检查,如果Bar不是明确的BarType超类型,则生成错误,然后优化掉未使用的局部变量。

Huh。。。不,真的,你能澄清一下你的意思吗?但请注意,这是在每个函数的基础上完成的,而不是一次完成整个类模板。@Ben我正在完成Ben所说的。他的意思是,如果模板中的某个函数从未被调用,它就不会被编译。这意味着您可以在其中编写完全无用的代码,而程序仍将编译,因为它实际上并不关心检查您未调用的函数。这对于普通类来说是不正确的,在普通类中,即使不使用函数,也会对其进行编译检查。@Paul:这也不完全正确。参见:保罗:同样,它不能是完全垃圾,它仍然必须是语法正确的C++。很明显,我只是想澄清一下。动态转换不是更好吗?@Paul:不。我们正在检查编译时类型typename模板参数,而不是动态类型..嗯??您应该重新查看预期的代码,因为main中的第二行不会编译Seond,缺少c,但第三行的编译与注释相反indicates@David哦,非常抱歉没问题。我只是想,如果我留下一条评论,你会得到通知,并四处去修复它:我不认为这有什么具体的原因。这是一种命名约定,用于提及单个参数化模板类或函数。如果使用多种类型,通常的表示法类似于T1、T2等,但同样没有附加字符串。你可以说出任何名字。在Stroustrup示例中,在某些地方指定它类似于typename容器。这是根据情况作出的选择。我在传达一种标准符号