关于C++模板的问题
A question about Template in C++
我知道C++模板的基础知识,但我仍在学习。我对以下代码有疑问:
#include <iostream>
using namespace std;
class PNG {
public:
static void draw() {
cout<<"PNG drawing"<<endl;
}
};
template <typename Image>
void draw() {
Image::draw();
}
int main() {
draw<PNG>();
}
函数draw()
,我将类型Image
传递给它,它将使用Image
draw()
方法。
template <typename Image>
void draw() {
Image::draw();
}
在这里,我传递Image
并想在Image
中使用draw()
方法,但是模板函数draw()
没有参数。所以我的问题是,如果我以这种方式调用这个模板函数draw()
main
:draw<PNG>();
允许它?模板函数draw()
如何知道PNG
是一个类,以及如何调用类成员函数draw()
?
你的第一个问题
如果我调用这个模板函数 draw(( 主要以这种方式: draw((;是 它允许吗?
正如您已经意识到的,如果没有函数参数可以弄清楚,编译器本身就无法推断出您的意思draw<PNG>
。
所以,你必须写(就像你已经做的那样(:
int main() {
draw<PNG>();
}
此处不能省略模板参数。
你的第二个问题
以及模板函数 draw(( 如何 知道 PNG 是一个类,以及如何 类成员函数 draw(( 是 叫?
当函数模板 (A( 使用参数 PNG
实例化时,生成的函数体如下所示 (B(:
// A:
template <typename Image>
void draw() {
Image::draw();
}
// B:
PNG::draw();
解析器知道,要使其正常工作,PNG
必须是命名空间或类/结构。如果不是,则函数将不会编译。
例如,假设您调用了draw<int>()
,您的代码将尝试调用int::draw()
,这是不可能的。
现在,由于SFINAE(查找!(,您不会因中断的int::draw()
调用而收到编译错误;此特定实例化将被禁止存在。你可能会被告知"没有匹配的函数draw()
",因为 - 忽略禁止的实例化 - 它可以选择使用的函数draw
不可能重载。
draw<PNG>();
PNG
将传递给模板参数 Image
。因此,编译器会实例化相应的模板。换句话说,使用模板参数生成的函数Image
被调用参数 PNG
替换。
由于PNG::draw()
是一个静态成员函数,因此不需要实例来调用它。所以
Image::draw(); => PNG::draw() ; // Template parameter substituted and the call
// is made.
你不能像这样简单地在主函数中调用draw()
:
draw();
需要将其用作模板函数或成员函数。
PNG dummy;
dummy.draw(); // Okay.
dummy::draw(); // Okay.
draw<PNG>(); // Okay.
draw(); // Not okay.
我不确定你第二个问题是什么意思。 在这种情况下,typename
关键字表示函数将接受恰好具有draw()
成员的未知类型的对象。
- 警告处理为错误这里有什么问题
- 最小硬币更换问题(自上而下方法)
- 为"adjacent"变量赋值时出现问题
- 我的神经网络不起作用 [XOR 问题]
- 在Ubuntu 16.04上安装Cilk时出现问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 编译包含字符串的代码时遇到问题
- Project Euler问题4的错误解决方案
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 静态数据成员的问题-修复链接错误会导致编译器错误
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 一个关于在C++中重载布尔运算符的问题
- 首要问题的答案让值班员搞错了
- setlocale的C++土耳其字符串问题
- 如何重构类层次结构以避免菱形问题
- 基于boost的程序的静态链接——zlib问题
- C++格式化输出问题
- 使用mongocxx驱动程序时包含头文件问题